]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'block'
authorJames Bottomley <James.Bottomley@suse.de>
Thu, 23 Dec 2010 05:29:40 +0000 (23:29 -0600)
committerJames Bottomley <James.Bottomley@suse.de>
Thu, 23 Dec 2010 05:29:40 +0000 (23:29 -0600)
1375 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/Locking
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/scsi/ChangeLog.megaraid_sas
Documentation/scsi/scsi_mid_low_api.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-kafa.c
arch/arm/mach-at91/board-picotux200.c
arch/arm/mach-at91/board-rm9200dk.c [moved from arch/arm/mach-at91/board-dk.c with 98% similarity]
arch/arm/mach-at91/board-rm9200ek.c [moved from arch/arm/mach-at91/board-ek.c with 98% similarity]
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-mmp/mmp2.c
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/board-zoom-peripherals.c
arch/arm/mach-omap2/include/mach/vmalloc.h
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/pm-debug.c
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/prcm-common.h
arch/arm/mach-omap2/serial.c
arch/arm/mach-pnx4008/include/mach/vmalloc.h
arch/arm/mach-pxa/palmtx.c
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/cache-v6.S
arch/arm/mm/cache-v7.S
arch/arm/mm/ioremap.c
arch/arm/mm/proc-macros.S
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-omap/counter_32k.c
arch/arm/plat-omap/sram.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/tools/mach-types
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/Kconfig
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/asm/unistd_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/syscalls_32.S
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/include/asm/openprom.h
arch/sparc/include/asm/oplib_32.h
arch/sparc/include/asm/oplib_64.h
arch/sparc/kernel/leon_kernel.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/sparc/prom/Makefile
arch/sparc/prom/console_32.c
arch/sparc/prom/console_64.c
arch/sparc/prom/devops_32.c [deleted file]
arch/sparc/prom/devops_64.c [deleted file]
arch/sparc/prom/misc_64.c
arch/sparc/prom/printf.c
arch/sparc/prom/tree_32.c
arch/sparc/prom/tree_64.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/Kconfig
arch/x86/crypto/ghash-clmulni-intel_glue.c
arch/x86/ia32/sys_ia32.c
arch/x86/include/asm/fixmap.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/paravirt.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/hw_nmi.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_64.S
arch/x86/kernel/hw_breakpoint.c
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/bsg.c
block/compat_ioctl.c
block/ioctl.c
drivers/acpi/ac.c
drivers/acpi/apei/erst.c
drivers/acpi/apei/hest.c
drivers/acpi/battery.c
drivers/acpi/ec.c
drivers/acpi/osl.c
drivers/acpi/power.c
drivers/acpi/processor_thermal.c
drivers/acpi/sleep.c
drivers/ata/libata-scsi.c
drivers/ata/sata_via.c
drivers/atm/adummy.c
drivers/atm/ambassador.c
drivers/atm/atmtcp.c
drivers/atm/eni.c
drivers/atm/firestream.c
drivers/atm/fore200e.c
drivers/atm/he.c
drivers/atm/horizon.c
drivers/atm/idt77252.c
drivers/atm/iphase.c
drivers/atm/lanai.c
drivers/atm/nicstar.c
drivers/atm/solos-pci.c
drivers/atm/zatm.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/bluetooth/ath3k.c
drivers/bluetooth/btusb.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/connector/connector.c
drivers/dma/Makefile
drivers/dma/at_hdmac.c
drivers/dma/fsldma.c
drivers/dma/fsldma.h
drivers/dma/imx-dma.c
drivers/dma/imx-sdma.c
drivers/dma/intel_mid_dma.c
drivers/dma/ioat/Makefile
drivers/dma/pch_dma.c
drivers/dma/ppc4xx/adma.c
drivers/dma/shdma.c
drivers/edac/Makefile
drivers/edac/amd64_edac.c
drivers/edac/edac_core.h
drivers/edac/edac_mc.c
drivers/edac/mce_amd_inj.c
drivers/firewire/net.c
drivers/firewire/ohci.c
drivers/firewire/sbp2.c
drivers/gpio/cs5535-gpio.c
drivers/gpu/drm/drm_crtc.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/adm1026.c
drivers/hwmon/i5k_amb.c
drivers/hwmon/it87.c
drivers/hwmon/lis3lv02d_i2c.c
drivers/hwmon/ltc4215.c
drivers/i2c/Kconfig
drivers/i2c/algos/Kconfig
drivers/i2c/busses/i2c-intel-mid.c
drivers/idle/intel_idle.c
drivers/infiniband/core/ud_header.c
drivers/infiniband/core/uverbs_cmd.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/md/raid10.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/maps/pxa2xx-flash.c
drivers/mtd/nand/omap2.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/b44.c
drivers/net/benet/be_cmds.c
drivers/net/benet/be_main.c
drivers/net/bnx2x/bnx2x.h
drivers/net/bnx2x/bnx2x_cmn.c
drivers/net/bnx2x/bnx2x_init_ops.h
drivers/net/bnx2x/bnx2x_main.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/caif/caif_shm_u5500.c
drivers/net/caif/caif_shmcore.c
drivers/net/caif/caif_spi.c
drivers/net/cxgb4/t4_hw.c
drivers/net/cxgb4vf/cxgb4vf_main.c
drivers/net/cxgb4vf/t4vf_hw.c
drivers/net/e1000/e1000_main.c
drivers/net/ehea/ehea_ethtool.c
drivers/net/ehea/ehea_main.c
drivers/net/enic/enic_main.c
drivers/net/gianfar.c
drivers/net/ifb.c
drivers/net/ipg.c
drivers/net/irda/sh_sir.c
drivers/net/ixgbe/ixgbe_main.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/Kconfig
drivers/net/phy/icplus.c
drivers/net/phy/marvell.c
drivers/net/ppp_generic.c
drivers/net/pppoe.c
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_main.c
drivers/net/qlge/qlge_mpi.c
drivers/net/r8169.c
drivers/net/sfc/efx.c
drivers/net/sfc/net_driver.h
drivers/net/sfc/nic.c
drivers/net/stmmac/stmmac_main.c
drivers/net/tile/Makefile [new file with mode: 0644]
drivers/net/tile/tilepro.c [new file with mode: 0644]
drivers/net/tulip/dmfe.c
drivers/net/ucc_geth.h
drivers/net/usb/hso.c
drivers/net/wan/hd64572.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/eeprom.c
drivers/net/wireless/ath/ath9k/eeprom.h
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/fw.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/ath/carl9170/usb.c
drivers/net/wireless/b43/sdio.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/orinoco/orinoco_cs.c
drivers/net/wireless/orinoco/orinoco_usb.c
drivers/net/wireless/orinoco/scan.c
drivers/net/wireless/orinoco/scan.h
drivers/net/wireless/orinoco/spectrum_cs.c
drivers/net/wireless/orinoco/wext.c
drivers/net/xen-netfront.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/pnp/pnpacpi/core.c
drivers/regulator/core.c
drivers/regulator/mc13783-regulator.c
drivers/regulator/tps6586x-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_aux.c
drivers/s390/scsi/zfcp_ccw.c
drivers/s390/scsi/zfcp_cfdc.c
drivers/s390/scsi/zfcp_dbf.c
drivers/s390/scsi/zfcp_dbf.h
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_ext.h
drivers/s390/scsi/zfcp_fc.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_qdio.c
drivers/s390/scsi/zfcp_scsi.c
drivers/s390/scsi/zfcp_sysfs.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/Makefile
drivers/scsi/bfa/bfa.h
drivers/scsi/bfa/bfa_cb_ioim.h [deleted file]
drivers/scsi/bfa/bfa_core.c
drivers/scsi/bfa/bfa_cs.h
drivers/scsi/bfa/bfa_defs.h
drivers/scsi/bfa/bfa_defs_svc.h
drivers/scsi/bfa/bfa_drv.c [deleted file]
drivers/scsi/bfa/bfa_fc.h
drivers/scsi/bfa/bfa_fcbuild.c
drivers/scsi/bfa/bfa_fcbuild.h
drivers/scsi/bfa/bfa_fcpim.c
drivers/scsi/bfa/bfa_fcpim.h
drivers/scsi/bfa/bfa_fcs.c
drivers/scsi/bfa/bfa_fcs.h
drivers/scsi/bfa/bfa_fcs_fcpim.c
drivers/scsi/bfa/bfa_fcs_lport.c
drivers/scsi/bfa/bfa_fcs_rport.c
drivers/scsi/bfa/bfa_hw_cb.c
drivers/scsi/bfa/bfa_hw_ct.c
drivers/scsi/bfa/bfa_ioc.c
drivers/scsi/bfa/bfa_ioc.h
drivers/scsi/bfa/bfa_ioc_cb.c
drivers/scsi/bfa/bfa_ioc_ct.c
drivers/scsi/bfa/bfa_modules.h
drivers/scsi/bfa/bfa_os_inc.h [deleted file]
drivers/scsi/bfa/bfa_plog.h
drivers/scsi/bfa/bfa_port.c
drivers/scsi/bfa/bfa_port.h
drivers/scsi/bfa/bfa_svc.c
drivers/scsi/bfa/bfa_svc.h
drivers/scsi/bfa/bfad.c
drivers/scsi/bfa/bfad_attr.c
drivers/scsi/bfa/bfad_debugfs.c
drivers/scsi/bfa/bfad_drv.h
drivers/scsi/bfa/bfad_im.c
drivers/scsi/bfa/bfad_im.h
drivers/scsi/bfa/bfi.h
drivers/scsi/bfa/bfi_cbreg.h
drivers/scsi/bfa/bfi_ctreg.h
drivers/scsi/bfa/bfi_ms.h
drivers/scsi/bnx2i/57xx_iscsi_constants.h
drivers/scsi/bnx2i/57xx_iscsi_hsi.h
drivers/scsi/bnx2i/bnx2i.h
drivers/scsi/bnx2i/bnx2i_hwi.c
drivers/scsi/bnx2i/bnx2i_init.c
drivers/scsi/bnx2i/bnx2i_iscsi.c
drivers/scsi/bnx2i/bnx2i_sysfs.c
drivers/scsi/dc395x.c
drivers/scsi/device_handler/scsi_dh.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/fcoe/fcoe.c
drivers/scsi/fcoe/libfcoe.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/hpsa.h
drivers/scsi/hptiop.c
drivers/scsi/ibmmca.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvfc.h
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/ipr.h
drivers/scsi/ips.c
drivers/scsi/libfc/fc_exch.c
drivers/scsi/libfc/fc_fcp.c
drivers/scsi/libfc/fc_libfc.h
drivers/scsi/libfc/fc_lport.c
drivers/scsi/libfc/fc_rport.c
drivers/scsi/libiscsi.c
drivers/scsi/libsas/sas_port.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_disc.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_hw.h
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_logmsg.h
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_mem.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli.h
drivers/scsi/lpfc/lpfc_sli4.h
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/lpfc/lpfc_vport.c
drivers/scsi/mac53c94.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/megaraid/Makefile
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c [moved from drivers/scsi/megaraid/megaraid_sas.c with 89% similarity]
drivers/scsi/megaraid/megaraid_sas_fp.c [new file with mode: 0644]
drivers/scsi/megaraid/megaraid_sas_fusion.c [new file with mode: 0644]
drivers/scsi/megaraid/megaraid_sas_fusion.h [new file with mode: 0644]
drivers/scsi/mesh.c
drivers/scsi/mpt2sas/mpi/mpi2.h
drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
drivers/scsi/mpt2sas/mpi/mpi2_history.txt
drivers/scsi/mpt2sas/mpi/mpi2_init.h
drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
drivers/scsi/mpt2sas/mpi/mpi2_raid.h
drivers/scsi/mpt2sas/mpi/mpi2_sas.h
drivers/scsi/mpt2sas/mpi/mpi2_tool.h
drivers/scsi/mpt2sas/mpt2sas_base.c
drivers/scsi/mpt2sas/mpt2sas_base.h
drivers/scsi/mpt2sas/mpt2sas_ctl.c
drivers/scsi/mpt2sas/mpt2sas_scsih.c
drivers/scsi/mpt2sas/mpt2sas_transport.c
drivers/scsi/ncr53c8xx.c
drivers/scsi/nsp32.c
drivers/scsi/osd/osd_initiator.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/pmcraid.h
drivers/scsi/ppa.c
drivers/scsi/ps3rom.c
drivers/scsi/qla1280.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_nx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/qla4xxx/ql4_dbg.c
drivers/scsi/qla4xxx/ql4_dbg.h
drivers/scsi/qla4xxx/ql4_def.h
drivers/scsi/qla4xxx/ql4_fw.h
drivers/scsi/qla4xxx/ql4_glbl.h
drivers/scsi/qla4xxx/ql4_init.c
drivers/scsi/qla4xxx/ql4_inline.h
drivers/scsi/qla4xxx/ql4_iocb.c
drivers/scsi/qla4xxx/ql4_isr.c
drivers/scsi/qla4xxx/ql4_mbx.c
drivers/scsi/qla4xxx/ql4_nvram.c
drivers/scsi/qla4xxx/ql4_nvram.h
drivers/scsi/qla4xxx/ql4_nx.c
drivers/scsi/qla4xxx/ql4_nx.h
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/qla4xxx/ql4_version.h
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/scsi_lib.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sd.c
drivers/scsi/st.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/kgdboc.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/spi/dw_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/atm/usbatm.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/vhost/vhost.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/modedb.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/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ioctl.h
fs/btrfs/ordered-data.c
fs/btrfs/ordered-data.h
fs/btrfs/orphan.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/ioctl.h
fs/ceph/locks.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/super.h
fs/cifs/Kconfig
fs/cifs/Makefile
fs/cifs/README
fs/cifs/cifs_fs_sb.h
fs/cifs/cifsacl.c
fs/cifs/cifsacl.h
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
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/ext4.h
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/namei.c
fs/ext4/page-io.c
fs/ext4/super.c
fs/fuse/file.c
fs/gfs2/quota.c
fs/ioctl.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/file.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/mount_clnt.c
fs/nfs/nfs2xdr.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/pagelist.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4state.c
fs/nfsd/xdr4.h
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
fs/xfs/xfs_rename.c
include/acpi/video.h
include/drm/i915_drm.h
include/drm/nouveau_drm.h
include/linux/acpi.h
include/linux/atmdev.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/hw_breakpoint.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/mfd/wm8994/pdata.h
include/linux/mmc/host.h
include/linux/module.h
include/linux/nfs_fs.h
include/linux/nfs_page.h
include/linux/nfs_xdr.h
include/linux/node.h
include/linux/page_cgroup.h
include/linux/pci_ids.h
include/linux/perf_event.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/snmp.h
include/linux/tty.h
include/linux/uio_driver.h
include/linux/usb.h
include/linux/video_output.h
include/linux/vmalloc.h
include/media/v4l2-common.h
include/net/af_unix.h
include/net/cfg80211.h
include/net/neighbour.h
include/net/sock.h
include/scsi/libfc.h
include/scsi/libfcoe.h
include/scsi/libiscsi.h
include/scsi/libsas.h
include/scsi/scsi.h
include/scsi/scsi_host.h
include/sound/sh_fsi.h
include/video/da8xx-fb.h
include/xen/events.h
include/xen/interface/io/ring.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/hw_breakpoint.c
kernel/irq/proc.c
kernel/irq_work.c
kernel/module.c
kernel/perf_event.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
kernel/workqueue.c
lib/debug_locks.c
mm/filemap.c
mm/hugetlb.c
mm/ksm.c
mm/memcontrol.c
mm/memory-failure.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/mmap.c
mm/nommu.c
mm/page_alloc.c
mm/pagewalk.c
mm/slub.c
mm/truncate.c
mm/vmalloc.c
mm/vmscan.c
mm/vmstat.c
net/atm/atm_sysfs.c
net/atm/resources.c
net/atm/resources.h
net/bluetooth/sco.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/core/timestamping.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/proc.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/ip6_tunnel.c
net/ipv6/sit.c
net/irda/af_irda.c
net/irda/irnet/irnet_ppp.c
net/irda/irttp.c
net/l2tp/l2tp_ip.c
net/llc/af_llc.c
net/mac80211/Kconfig
net/mac80211/rx.c
net/mac80211/tx.c
net/netfilter/ipvs/Kconfig
net/rds/rdma.c
net/sctp/socket.c
net/socket.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/x25/x25_link.c
net/xfrm/xfrm_hash.c
net/xfrm/xfrm_state.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/hda_eld.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.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/wm8580.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/codecs/wm_hubs.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
tools/perf/builtin-record.c
tools/perf/util/header.c
tools/perf/util/symbol.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 a91f30890011ddf69ba9b859484966c943db7fb5..b6426f15b4ae85f5469b962806004237b9b5607e 100644 (file)
@@ -173,12 +173,13 @@ prototypes:
        sector_t (*bmap)(struct address_space *, sector_t);
        int (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, int);
+       void (*freepage)(struct page *);
        int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        int (*launder_page) (struct page *);
 
 locking rules:
-       All except set_page_dirty may block
+       All except set_page_dirty and freepage may block
 
                        BKL     PageLocked(page)        i_mutex
 writepage:             no      yes, unlocks (see below)
@@ -193,6 +194,7 @@ perform_write:              no      n/a                     yes
 bmap:                  no
 invalidatepage:                no      yes
 releasepage:           no      yes
+freepage:              no      yes
 direct_IO:             no
 launder_page:          no      yes
 
@@ -288,6 +290,9 @@ buffers from the page in preparation for freeing it.  It returns zero to
 indicate that the buffers are (or may be) freeable.  If ->releasepage is zero,
 the kernel assumes that the fs has no private interest in the buffers.
 
+       ->freepage() is called when the kernel is done dropping the page
+from the page cache.
+
        ->launder_page() may be called prior to releasing a page if
 it is still found to be dirty. It returns zero if the page was successfully
 cleaned, or an error value if not. Note that in order to prevent the page
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..20899e095e7e6879580b53aa9aa0282fb4b5ce63 100644 (file)
@@ -534,6 +534,7 @@ struct address_space_operations {
        sector_t (*bmap)(struct address_space *, sector_t);
        int (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, int);
+       void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        struct page* (*get_xip_page)(struct address_space *, sector_t,
@@ -660,11 +661,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.
 
@@ -679,6 +679,12 @@ struct address_space_operations {
         need to ensure this.  Possibly it can clear the PageUptodate
         bit if it cannot free private data yet.
 
+  freepage: freepage is called once the page is no longer visible in
+        the page cache in order to allow the cleanup of any private
+       data. Since it may be called by the memory reclaimer, it
+       should not assume that the original address_space mapping still
+       exists, and it should not block.
+
   direct_IO: called by the generic read/write routines to perform
         direct_IO - that is IO requests which bypass the page cache
         and transfer data directly between the storage and the
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.
index 00301ed9c3715596b35411f46ff31243412444dd..b64d10d221ecbd6473876f7c7c725c35c16366d2 100644 (file)
@@ -1,3 +1,25 @@
+Release Date    : Tues.  Dec 14, 2010 17:00:00 PST 2010 -
+                       (emaild-id:megaraidlinux@lsi.com)
+                       Adam Radford
+Current Version : 00.00.05.29-rc1
+Old Version     : 00.00.04.31-rc1
+    1. Rename megaraid_sas.c to megaraid_sas_base.c.
+    2. Update GPL headers.
+    3. Add MSI-X support and 'msix_disable' module parameter.
+    4. Use lowest memory bar (for SR-IOV VF support).
+    5. Add struct megasas_instance_temlate changes, and change all code to use
+       new instance entries:
+
+       irqreturn_t (*service_isr )(int irq, void *devp);
+       void (*tasklet)(unsigned long);
+       u32 (*init_adapter)(struct megasas_instance *);
+       u32 (*build_and_issue_cmd) (struct megasas_instance *,
+       struct scsi_cmnd *);
+       void (*issue_dcmd) (struct megasas_instance *instance,
+                              struct megasas_cmd *cmd);
+
+   6. Add code to support MegaRAID 9265/9285 controllers device id (0x5b).
+-------------------------------------------------------------------------------
 1 Release Date    : Thur.  May 03, 2010 09:12:45 PST 2009 -
                        (emaild-id:megaraidlinux@lsi.com)
                        Bo Yang
index 570ef2b3d79b16c2f57c01f88d5de3a1a954f6a4..df322c1034667eebbced0792f2c8a7c733e5cf78 100644 (file)
@@ -1044,9 +1044,9 @@ Details:
 
 
 /**
- *      queuecommand - queue scsi command, invoke 'done' on completion
+ *      queuecommand - queue scsi command, invoke scp->scsi_done on completion
+ *      @shost: pointer to the scsi host object
  *      @scp: pointer to scsi command object
- *      @done: function pointer to be invoked on completion
  *
  *      Returns 0 on success.
  *
@@ -1074,42 +1074,45 @@ Details:
  *
  *      Other types of errors that are detected immediately may be
  *      flagged by setting scp->result to an appropriate value,
- *      invoking the 'done' callback, and then returning 0 from this
- *      function. If the command is not performed immediately (and the
- *      LLD is starting (or will start) the given command) then this
- *      function should place 0 in scp->result and return 0.
+ *      invoking the scp->scsi_done callback, and then returning 0
+ *      from this function. If the command is not performed
+ *      immediately (and the LLD is starting (or will start) the given
+ *      command) then this function should place 0 in scp->result and
+ *      return 0.
  *
  *      Command ownership.  If the driver returns zero, it owns the
- *      command and must take responsibility for ensuring the 'done'
- *      callback is executed.  Note: the driver may call done before
- *      returning zero, but after it has called done, it may not
- *      return any value other than zero.  If the driver makes a
- *      non-zero return, it must not execute the command's done
- *      callback at any time.
- *
- *      Locks: struct Scsi_Host::host_lock held on entry (with "irqsave")
- *             and is expected to be held on return.
+ *      command and must take responsibility for ensuring the
+ *      scp->scsi_done callback is executed.  Note: the driver may
+ *      call scp->scsi_done before returning zero, but after it has
+ *      called scp->scsi_done, it may not return any value other than
+ *      zero.  If the driver makes a non-zero return, it must not
+ *      execute the command's scsi_done callback at any time.
+ *
+ *      Locks: up to and including 2.6.36, struct Scsi_Host::host_lock
+ *             held on entry (with "irqsave") and is expected to be
+ *             held on return. From 2.6.37 onwards, queuecommand is
+ *             called without any locks held.
  *
  *      Calling context: in interrupt (soft irq) or process context
  *
- *      Notes: This function should be relatively fast. Normally it will
- *      not wait for IO to complete. Hence the 'done' callback is invoked 
- *      (often directly from an interrupt service routine) some time after
- *      this function has returned. In some cases (e.g. pseudo adapter 
- *      drivers that manufacture the response to a SCSI INQUIRY)
- *      the 'done' callback may be invoked before this function returns.
- *      If the 'done' callback is not invoked within a certain period
- *      the SCSI mid level will commence error processing.
- *      If a status of CHECK CONDITION is placed in "result" when the
- *      'done' callback is invoked, then the LLD driver should 
- *      perform autosense and fill in the struct scsi_cmnd::sense_buffer
+ *      Notes: This function should be relatively fast. Normally it
+ *      will not wait for IO to complete. Hence the scp->scsi_done
+ *      callback is invoked (often directly from an interrupt service
+ *      routine) some time after this function has returned. In some
+ *      cases (e.g. pseudo adapter drivers that manufacture the
+ *      response to a SCSI INQUIRY) the scp->scsi_done callback may be
+ *      invoked before this function returns.  If the scp->scsi_done
+ *      callback is not invoked within a certain period the SCSI mid
+ *      level will commence error processing.  If a status of CHECK
+ *      CONDITION is placed in "result" when the scp->scsi_done
+ *      callback is invoked, then the LLD driver should perform
+ *      autosense and fill in the struct scsi_cmnd::sense_buffer
  *      array. The scsi_cmnd::sense_buffer array is zeroed prior to
  *      the mid level queuing a command to an LLD.
  *
  *      Defined in: LLD
  **/
-    int queuecommand(struct scsi_cmnd * scp, 
-                     void (*done)(struct scsi_cmnd *))
+    int queuecommand(struct Scsi_Host *shost, struct scsi_cmnd * scp)
 
 
 /**
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..6a588873cf8d2da8b00f803a1dcd8d96841292bd 100644 (file)
@@ -559,14 +559,14 @@ W:        http://maxim.org.za/at91_26.html
 S:     Maintained
 
 ARM/BCMRING ARM ARCHITECTURE
-M:     Leo Chen <leochen@broadcom.com>
+M:     Jiandong Zheng <jdzheng@broadcom.com>
 M:     Scott Branden <sbranden@broadcom.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-bcmring
 
 ARM/BCMRING MTD NAND DRIVER
-M:     Leo Chen <leochen@broadcom.com>
+M:     Jiandong Zheng <jdzheng@broadcom.com>
 M:     Scott Branden <sbranden@broadcom.com>
 L:     linux-mtd@lists.infradead.org
 S:     Maintained
@@ -815,7 +815,7 @@ F:  drivers/mmc/host/msm_sdcc.c
 F:     drivers/mmc/host/msm_sdcc.h
 F:     drivers/serial/msm_serial.h
 F:     drivers/serial/msm_serial.c
-T:     git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git
+T:     git git://codeaurora.org/quic/kernel/davidb/linux-msm.git
 S:     Maintained
 
 ARM/TOSA MACHINE SUPPORT
@@ -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>
@@ -5920,7 +5932,6 @@ F:        include/linux/tty.h
 
 TULIP NETWORK DRIVERS
 M:     Grant Grundler <grundler@parisc-linux.org>
-M:     Kyle McMartin <kyle@mcmartin.ca>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/tulip/
@@ -6572,6 +6583,15 @@ F:       include/linux/mfd/wm8400*
 F:     include/sound/wm????.h
 F:     sound/soc/codecs/wm*
 
+WORKQUEUE
+M:     Tejun Heo <tj@kernel.org>
+L:     linux-kernel@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git
+S:     Maintained
+F:     include/linux/workqueue.h
+F:     kernel/workqueue.c
+F:     Documentation/workqueue.txt
+
 X.25 NETWORK LAYER
 M:     Andrew Hendry <andrew.hendry@gmail.com>
 L:     linux-x25@vger.kernel.org
index ab5359db3d177b2e4a83823baa15da908e5b395b..5aa44278d95686e9719f38592599b094a72a1366 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 37
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc6
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
index db524e75c4a21e4f45bc4b72e459adcdaf1dda4b..d56d21c0573ba519b36d7f1e4012eb609dfbb664 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)
@@ -1311,7 +1311,7 @@ config HZ
 
 config THUMB2_KERNEL
        bool "Compile the kernel in Thumb-2 mode"
-       depends on CPU_V7 && EXPERIMENTAL
+       depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
        select AEABI
        select ARM_ASM_UNIFIED
        help
@@ -1759,7 +1759,7 @@ comment "At least one emulation must be selected"
 
 config FPE_NWFPE
        bool "NWFPE math emulation"
-       depends on !AEABI || OABI_COMPAT
+       depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL
        ---help---
          Say Y to include the NWFPE floating point emulator in the kernel.
          This is necessary to run most binaries. Linux does not currently
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)
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);
 }
similarity index 98%
rename from arch/arm/mach-at91/board-dk.c
rename to arch/arm/mach-at91/board-rm9200dk.c
index e14f0e165680ed39b5a9be326e661b9b415cb1bd..4c1047c8200df94466a81337779a4cfcfb1c7d7a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91/board-dk.c
+ * linux/arch/arm/mach-at91/board-rm9200dk.c
  *
  *  Copyright (C) 2005 SAN People
  *
@@ -91,10 +91,12 @@ static struct at91_cf_data __initdata dk_cf_data = {
        // .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 */
similarity index 98%
rename from arch/arm/mach-at91/board-ek.c
rename to arch/arm/mach-at91/board-rm9200ek.c
index 56e92c4bbc2a3222c87ddda4c178b13b33bb75dc..9df1be8818c0bdf8eb9ff47086e0a68ee7c21294 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91/board-ek.c
+ * linux/arch/arm/mach-at91/board-rm9200ek.c
  *
  *  Copyright (C) 2005 SAN People
  *
@@ -84,12 +84,14 @@ static struct at91_udc_data __initdata ek_udc_data = {
        .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 */
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 daf3993349f81986fa8f5b90ca0c4bcb4e7acc8a..2e3dd08ccc3f3f1d062eaac583b92109e39c31f4 100644 (file)
@@ -126,7 +126,6 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000);
 static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000);
 static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000);
 static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000);
-static APBC_CLK(rtc, MMP2_RTC, 0, 32768);
 
 static APMU_CLK(nand, NAND, 0xbf, 100000000);
 
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 86c9b210295214c175638df2997745d2643cd447..9db9203667df504c5b5731680b3f75077ae79b6d 100644 (file)
@@ -216,7 +216,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
        {
                .name           = "wl1271",
                .mmc            = 3,
-               .caps           = MMC_CAP_4_BIT_DATA,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
                .gpio_wp        = -EINVAL,
                .gpio_cd        = -EINVAL,
                .nonremovable   = true,
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 40562ddd3ee4fe29ea1e173a61d778225d28b01d..a1939b1e6f82e0d30ca77b8b4156c27eb6f1c4ce 100644 (file)
@@ -297,7 +297,7 @@ static int __init _omap2_init_reprogram_sdrc(void)
                return 0;
 
        dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
-       if (!dpll3_m2_ck)
+       if (IS_ERR(dpll3_m2_ck))
                return -EINVAL;
 
        rate = clk_get_rate(dpll3_m2_ck);
index 5e81517a7af2040a8bff6a2e2eabc9a96e300b76..a8afb610c7d83fa7a500445ea4647d4935d26e09 100644 (file)
@@ -161,6 +161,23 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
                printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
 }
 
+void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
+{
+       u32 tick_rate, cycles;
+
+       if (!seconds && !milliseconds)
+               return;
+
+       tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+       cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
+       omap_dm_timer_stop(gptimer_wakeup);
+       omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+       pr_info("PM: Resume timer in %u.%03u secs"
+               " (%d ticks at %d ticks/sec.)\n",
+               seconds, milliseconds, cycles, tick_rate);
+}
+
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -354,23 +371,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
        pwrdm->timer = t;
 }
 
-void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
-{
-       u32 tick_rate, cycles;
-
-       if (!seconds && !milliseconds)
-               return;
-
-       tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
-       cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
-       omap_dm_timer_stop(gptimer_wakeup);
-       omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
-
-       pr_info("PM: Resume timer in %u.%03u secs"
-               " (%d ticks at %d ticks/sec.)\n",
-               seconds, milliseconds, cycles, tick_rate);
-}
-
 static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
 {
        struct seq_file *s = (struct seq_file *)user;
index a40457d81927e256ec1f6af538acf038c7e11eb1..aaeea49b9bdd80f6e51affaee9c3a38ff6e2368f 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>
 #include <plat/powerdomain.h>
 #include <plat/clockdomain.h>
 
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+       return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+       return false;
+}
+#endif
+
 static void (*omap2_sram_idle)(void);
 static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
                                  void __iomem *sdrc_power);
@@ -118,6 +132,11 @@ 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 (!is_suspending())
+               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 +150,9 @@ static void omap2_enter_full_retention(void)
        omap_uart_resume_idle(1);
        omap_uart_resume_idle(0);
 
+       if (!is_suspending())
+               release_console_sem();
+
 no_sleep:
        if (omap2_pm_debug) {
                unsigned long long tmp;
@@ -277,6 +299,12 @@ out:
        local_irq_enable();
 }
 
+static int omap2_pm_begin(suspend_state_t state)
+{
+       suspend_state = state;
+       return 0;
+}
+
 static int omap2_pm_prepare(void)
 {
        /* We cannot sleep in idle until we have resumed */
@@ -326,10 +354,17 @@ static void omap2_pm_finish(void)
        enable_hlt();
 }
 
+static void omap2_pm_end(void)
+{
+       suspend_state = PM_SUSPEND_ON;
+}
+
 static struct platform_suspend_ops omap_pm_ops = {
+       .begin          = omap2_pm_begin,
        .prepare        = omap2_pm_prepare,
        .enter          = omap2_pm_enter,
        .finish         = omap2_pm_finish,
+       .end            = omap2_pm_end,
        .valid          = suspend_valid_only_mem,
 };
 
index 75c0cd13ad8e0e78ca9686f35d9ec18b370cb6db..648b8c50d02422eeda2146cf3d3ebbe4b44d5a75 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>
 #include "sdrc.h"
 #include "control.h"
 
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+       return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+       return false;
+}
+#endif
+
 /* Scratchpad offsets */
 #define OMAP343X_TABLE_ADDRESS_OFFSET     0xc4
 #define OMAP343X_TABLE_VALUE_OFFSET       0xc0
@@ -385,6 +399,13 @@ void omap_sram_idle(void)
                omap3_enable_io_chain();
        }
 
+       /* Block console output in case it is on one of the OMAP UARTs */
+       if (!is_suspending())
+               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 +484,10 @@ void omap_sram_idle(void)
                omap_uart_resume_idle(3);
        }
 
+       if (!is_suspending())
+               release_console_sem();
+
+console_still_active:
        /* Disable IO-PAD and IO-CHAIN wakeup */
        if (omap3_has_io_wakeup() &&
            (per_next_state < PWRDM_POWER_ON ||
@@ -504,8 +529,6 @@ out:
 }
 
 #ifdef CONFIG_SUSPEND
-static suspend_state_t suspend_state;
-
 static int omap3_pm_prepare(void)
 {
        disable_hlt();
index 298a22a754e20a56e428aeaed051cdd7b2b923f7..f81acee4738dea03f64576b6a6288282002def39 100644 (file)
 #define OMAP24XX_EN_GPT1_MASK                          (1 << 0)
 
 /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
-#define OMAP24XX_ST_GPIOS_SHIFT                                (1 << 2)
-#define OMAP24XX_ST_GPIOS_MASK                         2
-#define OMAP24XX_ST_GPT1_SHIFT                         (1 << 0)
-#define OMAP24XX_ST_GPT1_MASK                          0
+#define OMAP24XX_ST_GPIOS_SHIFT                                2
+#define OMAP24XX_ST_GPIOS_MASK                         (1 << 2)
+#define OMAP24XX_ST_GPT1_SHIFT                         0
+#define OMAP24XX_ST_GPT1_MASK                          (1 << 0)
 
 /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
-#define OMAP2430_ST_MDM_SHIFT                          (1 << 0)
+#define OMAP2430_ST_MDM_SHIFT                          0
+#define OMAP2430_ST_MDM_MASK                           (1 << 0)
 
 
 /* 3430 register bits shared between CM & PRM registers */
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 d2060a1d1d6820bcaf796e1a256a92989ce45365..e5c9932b75887914ec1c95b94692322b98f0e4b1 100644 (file)
@@ -241,7 +241,8 @@ static inline void palmtx_keys_init(void) {}
 /******************************************************************************
  * NAND Flash
  ******************************************************************************/
-#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE)
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+       defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
 static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
                                 unsigned int ctrl)
 {
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 99fa688dfadd305113670aa48ea185a9899f8e5b..c96fa1b3f49f5d78b670289a1d8fc8ccf3b38b30 100644 (file)
@@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area)
  *     - end     - virtual end address of region
  */
 v6_dma_inv_range:
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrb    r2, [r0]                        @ read for ownership
+       strb    r2, [r0]                        @ write for ownership
+#endif
        tst     r0, #D_CACHE_LINE_SIZE - 1
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
@@ -211,6 +215,10 @@ v6_dma_inv_range:
        mcrne   p15, 0, r0, c7, c11, 1          @ clean unified line
 #endif
        tst     r1, #D_CACHE_LINE_SIZE - 1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrneb  r2, [r1, #-1]                   @ read for ownership
+       strneb  r2, [r1, #-1]                   @ write for ownership
+#endif
        bic     r1, r1, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
        mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D line
@@ -218,10 +226,6 @@ v6_dma_inv_range:
        mcrne   p15, 0, r1, c7, c15, 1          @ clean & invalidate unified line
 #endif
 1:
-#ifdef CONFIG_DMA_CACHE_RWFO
-       ldr     r2, [r0]                        @ read for ownership
-       str     r2, [r0]                        @ write for ownership
-#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c6, 1           @ invalidate D line
 #else
@@ -229,6 +233,10 @@ v6_dma_inv_range:
 #endif
        add     r0, r0, #D_CACHE_LINE_SIZE
        cmp     r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrlo   r2, [r0]                        @ read for ownership
+       strlo   r2, [r0]                        @ write for ownership
+#endif
        blo     1b
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
@@ -263,12 +271,12 @@ v6_dma_clean_range:
  *     - end     - virtual end address of region
  */
 ENTRY(v6_dma_flush_range)
-       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
-1:
 #ifdef CONFIG_DMA_CACHE_RWFO
-       ldr     r2, [r0]                        @ read for ownership
-       str     r2, [r0]                        @ write for ownership
+       ldrb    r2, [r0]                @ read for ownership
+       strb    r2, [r0]                @ write for ownership
 #endif
+       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
+1:
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
 #else
@@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range)
 #endif
        add     r0, r0, #D_CACHE_LINE_SIZE
        cmp     r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrlob  r2, [r0]                        @ read for ownership
+       strlob  r2, [r0]                        @ write for ownership
+#endif
        blo     1b
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
index a3ebf7a4f49b2b404da115a58e7fdf6923792625..6136e68ce953d038ef0fa92b8211a3c477ef8e83 100644 (file)
@@ -173,15 +173,22 @@ ENTRY(v7_coherent_user_range)
  UNWIND(.fnstart               )
        dcache_line_size r2, r3
        sub     r3, r2, #1
-       bic     r0, r0, r3
+       bic     r12, r0, r3
 1:
- USER( mcr     p15, 0, r0, c7, c11, 1  )       @ clean D line to the point of unification
+ USER( mcr     p15, 0, r12, c7, c11, 1 )       @ clean D line to the point of unification
+       add     r12, r12, r2
+       cmp     r12, r1
+       blo     1b
        dsb
- USER( mcr     p15, 0, r0, c7, c5, 1   )       @ invalidate I line
-       add     r0, r0, r2
+       icache_line_size r2, r3
+       sub     r3, r2, #1
+       bic     r12, r0, r3
 2:
-       cmp     r0, r1
-       blo     1b
+ USER( mcr     p15, 0, r12, c7, c5, 1  )       @ invalidate I line
+       add     r12, r12, r2
+       cmp     r12, r1
+       blo     2b
+3:
        mov     r0, #0
        ALT_SMP(mcr     p15, 0, r0, c7, c1, 6)  @ invalidate BTB Inner Shareable
        ALT_UP(mcr      p15, 0, r0, c7, c5, 6)  @ invalidate BTB
@@ -194,10 +201,10 @@ ENTRY(v7_coherent_user_range)
  * isn't mapped, just try the next page.
  */
 9001:
-       mov     r0, r0, lsr #12
-       mov     r0, r0, lsl #12
-       add     r0, r0, #4096
-       b       2b
+       mov     r12, r12, lsr #12
+       mov     r12, r12, lsl #12
+       add     r12, r12, #4096
+       b       3b
  UNWIND(.fnend         )
 ENDPROC(v7_coherent_kern_range)
 ENDPROC(v7_coherent_user_range)
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 7d63beaf97456541c0718c84b475b844194156e6..b795afd0a2c620ad1e8f774b1c166bc8639b2847 100644 (file)
        .endm
 
 /*
- * cache_line_size - get the cache line size from the CSIDR register
- * (available on ARMv7+). It assumes that the CSSR register was configured
- * to access the L1 data cache CSIDR.
+ * dcache_line_size - get the minimum D-cache line size from the CTR register
+ * on ARMv7.
  */
        .macro  dcache_line_size, reg, tmp
-       mrc     p15, 1, \tmp, c0, c0, 0         @ read CSIDR
-       and     \tmp, \tmp, #7                  @ cache line size encoding
-       mov     \reg, #16                       @ size offset
+       mrc     p15, 0, \tmp, c0, c0, 1         @ read ctr
+       lsr     \tmp, \tmp, #16
+       and     \tmp, \tmp, #0xf                @ cache line size encoding
+       mov     \reg, #4                        @ bytes per word
        mov     \reg, \reg, lsl \tmp            @ actual cache line size
        .endm
 
+/*
+ * icache_line_size - get the minimum I-cache line size from the CTR register
+ * on ARMv7.
+ */
+       .macro  icache_line_size, reg, tmp
+       mrc     p15, 0, \tmp, c0, c0, 1         @ read ctr
+       and     \tmp, \tmp, #0xf                @ cache line size encoding
+       mov     \reg, #4                        @ bytes per word
+       mov     \reg, \reg, lsl \tmp            @ actual cache line size
+       .endm
 
 /*
  * Sanity check the PTE configuration for the code below - which makes
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 155fe43a672bc47fde734dc76e10fb844e9b22e5..8722a136f3a5bee844f5643dd195c95f077db666 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/err.h>
 
 #include <plat/common.h>
 #include <plat/board.h>
@@ -164,7 +165,7 @@ static int __init omap_init_clocksource_32k(void)
                        return -ENODEV;
 
                sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
-               if (sync_32k_ick)
+               if (!IS_ERR(sync_32k_ick))
                        clk_enable(sync_32k_ick);
 
                clocksource_32k.mult = clocksource_hz2mult(32768,
index e2c8eebe6b3a54a1ab7c0a9ffa25f280117ceb04..74dac419d328297a4347b8a29ce1d5c150af1480 100644 (file)
@@ -166,7 +166,7 @@ static void __init omap_detect_sram(void)
                     cpu_is_omap1710())
                        omap_sram_size = 0x4000;        /* 16K */
                else if (cpu_is_omap1611())
-                       omap_sram_size = 0x3e800;       /* 250K */
+                       omap_sram_size = SZ_256K;
                else {
                        printk(KERN_ERR "Could not detect SRAM size\n");
                        omap_sram_size = 0x4000;
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 55590a4d87c932984404d1df13ca4c296c9d7117..2fea897ebeb12959415120a7c1cdcaf5d8ac8fee 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Thu Sep 9 22:43:01 2010
+# Last update: Sun Dec 12 23:24:27 2010
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -2321,7 +2321,7 @@ mx31txtr          MACH_MX31TXTR           MX31TXTR                2332
 u380                   MACH_U380               U380                    2333
 oamp3_hualu            MACH_HUALU_BOARD        HUALU_BOARD             2334
 npcmx50                        MACH_NPCMX50            NPCMX50                 2335
-mx51_lange51           MACH_MX51_LANGE51       MX51_LANGE51            2336
+mx51_efikamx           MACH_MX51_EFIKAMX       MX51_EFIKAMX            2336
 mx51_lange52           MACH_MX51_LANGE52       MX51_LANGE52            2337
 riom                   MACH_RIOM               RIOM                    2338
 comcas                 MACH_COMCAS             COMCAS                  2339
@@ -2355,7 +2355,7 @@ at91sam9263cs             MACH_AT91SAM9263CS      AT91SAM9263CS           2366
 csb732                 MACH_CSB732             CSB732                  2367
 u8500                  MACH_U8500              U8500                   2368
 huqiu                  MACH_HUQIU              HUQIU                   2369
-mx51_kunlun            MACH_MX51_KUNLUN        MX51_KUNLUN             2370
+mx51_efikasb           MACH_MX51_EFIKASB       MX51_EFIKASB            2370
 pmt1g                  MACH_PMT1G              PMT1G                   2371
 htcelf                 MACH_HTCELF             HTCELF                  2372
 armadillo420           MACH_ARMADILLO420       ARMADILLO420            2373
@@ -2971,7 +2971,7 @@ premierwave_en            MACH_PREMIERWAVE_EN     PREMIERWAVE_EN          2985
 wasabi                 MACH_WASABI             WASABI                  2986
 vivow                  MACH_VIVOW              VIVOW                   2987
 mx50_rdp               MACH_MX50_RDP           MX50_RDP                2988
-universal              MACH_UNIVERSAL          UNIVERSAL               2989
+universal_c210         MACH_UNIVERSAL_C210     UNIVERSAL_C210          2989
 real6410               MACH_REAL6410           REAL6410                2990
 spx_sakura             MACH_SPX_SAKURA         SPX_SAKURA              2991
 ij3k_2440              MACH_IJ3K_2440          IJ3K_2440               2992
@@ -3044,3 +3044,178 @@ harvest_desoto          MACH_HARVEST_DESOTO     HARVEST_DESOTO          3059
 msm8x60_qrdc           MACH_MSM8X60_QRDC       MSM8X60_QRDC            3060
 spear900               MACH_SPEAR900           SPEAR900                3061
 pcontrol_g20           MACH_PCONTROL_G20       PCONTROL_G20            3062
+rdstor                 MACH_RDSTOR             RDSTOR                  3063
+usdloader              MACH_USDLOADER          USDLOADER               3064
+tsoploader             MACH_TSOPLOADER         TSOPLOADER              3065
+kronos                 MACH_KRONOS             KRONOS                  3066
+ffcore                 MACH_FFCORE             FFCORE                  3067
+mone                   MACH_MONE               MONE                    3068
+unit2s                 MACH_UNIT2S             UNIT2S                  3069
+acer_a5                        MACH_ACER_A5            ACER_A5                 3070
+etherpro_isp           MACH_ETHERPRO_ISP       ETHERPRO_ISP            3071
+stretchs7000           MACH_STRETCHS7000       STRETCHS7000            3072
+p87_smartsim           MACH_P87_SMARTSIM       P87_SMARTSIM            3073
+tulip                  MACH_TULIP              TULIP                   3074
+sunflower              MACH_SUNFLOWER          SUNFLOWER               3075
+rib                    MACH_RIB                RIB                     3076
+clod                   MACH_CLOD               CLOD                    3077
+rump                   MACH_RUMP               RUMP                    3078
+tenderloin             MACH_TENDERLOIN         TENDERLOIN              3079
+shortloin              MACH_SHORTLOIN          SHORTLOIN               3080
+crespo                 MACH_CRESPO             CRESPO                  3081
+antares                        MACH_ANTARES            ANTARES                 3082
+wb40n                  MACH_WB40N              WB40N                   3083
+herring                        MACH_HERRING            HERRING                 3084
+naxy400                        MACH_NAXY400            NAXY400                 3085
+naxy1200               MACH_NAXY1200           NAXY1200                3086
+vpr200                 MACH_VPR200             VPR200                  3087
+bug20                  MACH_BUG20              BUG20                   3088
+goflexnet              MACH_GOFLEXNET          GOFLEXNET               3089
+torbreck               MACH_TORBRECK           TORBRECK                3090
+saarb_mg1              MACH_SAARB_MG1          SAARB_MG1               3091
+callisto               MACH_CALLISTO           CALLISTO                3092
+multhsu                        MACH_MULTHSU            MULTHSU                 3093
+saluda                 MACH_SALUDA             SALUDA                  3094
+pemp_omap3_apollo      MACH_PEMP_OMAP3_APOLLO  PEMP_OMAP3_APOLLO       3095
+vc0718                 MACH_VC0718             VC0718                  3096
+mvblx                  MACH_MVBLX              MVBLX                   3097
+inhand_apeiron         MACH_INHAND_APEIRON     INHAND_APEIRON          3098
+inhand_fury            MACH_INHAND_FURY        INHAND_FURY             3099
+inhand_siren           MACH_INHAND_SIREN       INHAND_SIREN            3100
+hdnvp                  MACH_HDNVP              HDNVP                   3101
+softwinner             MACH_SOFTWINNER         SOFTWINNER              3102
+prima2_evb             MACH_PRIMA2_EVB         PRIMA2_EVB              3103
+nas6210                        MACH_NAS6210            NAS6210                 3104
+unisdev                        MACH_UNISDEV            UNISDEV                 3105
+sbca11                 MACH_SBCA11             SBCA11                  3106
+saga                   MACH_SAGA               SAGA                    3107
+ns_k330                        MACH_NS_K330            NS_K330                 3108
+tanna                  MACH_TANNA              TANNA                   3109
+imate8502              MACH_IMATE8502          IMATE8502               3110
+aspen                  MACH_ASPEN              ASPEN                   3111
+daintree_cwac          MACH_DAINTREE_CWAC      DAINTREE_CWAC           3112
+zmx25                  MACH_ZMX25              ZMX25                   3113
+maple1                 MACH_MAPLE1             MAPLE1                  3114
+qsd8x72_surf           MACH_QSD8X72_SURF       QSD8X72_SURF            3115
+qsd8x72_ffa            MACH_QSD8X72_FFA        QSD8X72_FFA             3116
+abilene                        MACH_ABILENE            ABILENE                 3117
+eigen_ttr              MACH_EIGEN_TTR          EIGEN_TTR               3118
+iomega_ix2_200         MACH_IOMEGA_IX2_200     IOMEGA_IX2_200          3119
+coretec_vcx7400                MACH_CORETEC_VCX7400    CORETEC_VCX7400         3120
+santiago               MACH_SANTIAGO           SANTIAGO                3121
+mx257sol               MACH_MX257SOL           MX257SOL                3122
+strasbourg             MACH_STRASBOURG         STRASBOURG              3123
+msm8x60_fluid          MACH_MSM8X60_FLUID      MSM8X60_FLUID           3124
+smartqv5               MACH_SMARTQV5           SMARTQV5                3125
+smartqv3               MACH_SMARTQV3           SMARTQV3                3126
+smartqv7               MACH_SMARTQV7           SMARTQV7                3127
+paz00                  MACH_PAZ00              PAZ00                   3128
+acmenetusfoxg20                MACH_ACMENETUSFOXG20    ACMENETUSFOXG20         3129
+htcwillow              MACH_HTCWILLOW          HTCWILLOW               3130
+fwbd_0404              MACH_FWBD_0404          FWBD_0404               3131
+hdgu                   MACH_HDGU               HDGU                    3132
+pyramid                        MACH_PYRAMID            PYRAMID                 3133
+epiphan                        MACH_EPIPHAN            EPIPHAN                 3134
+omap_bender            MACH_OMAP_BENDER        OMAP_BENDER             3135
+gurnard                        MACH_GURNARD            GURNARD                 3136
+gtl_it5100             MACH_GTL_IT5100         GTL_IT5100              3137
+bcm2708                        MACH_BCM2708            BCM2708                 3138
+mx51_ggc               MACH_MX51_GGC           MX51_GGC                3139
+sharespace             MACH_SHARESPACE         SHARESPACE              3140
+haba_knx_explorer      MACH_HABA_KNX_EXPLORER  HABA_KNX_EXPLORER       3141
+simtec_kirkmod         MACH_SIMTEC_KIRKMOD     SIMTEC_KIRKMOD          3142
+crux                   MACH_CRUX               CRUX                    3143
+mx51_bravo             MACH_MX51_BRAVO         MX51_BRAVO              3144
+charon                 MACH_CHARON             CHARON                  3145
+picocom3               MACH_PICOCOM3           PICOCOM3                3146
+picocom4               MACH_PICOCOM4           PICOCOM4                3147
+serrano                        MACH_SERRANO            SERRANO                 3148
+doubleshot             MACH_DOUBLESHOT         DOUBLESHOT              3149
+evsy                   MACH_EVSY               EVSY                    3150
+huashan                        MACH_HUASHAN            HUASHAN                 3151
+lausanne               MACH_LAUSANNE           LAUSANNE                3152
+emerald                        MACH_EMERALD            EMERALD                 3153
+tqma35                 MACH_TQMA35             TQMA35                  3154
+marvel                 MACH_MARVEL             MARVEL                  3155
+manuae                 MACH_MANUAE             MANUAE                  3156
+chacha                 MACH_CHACHA             CHACHA                  3157
+lemon                  MACH_LEMON              LEMON                   3158
+csc                    MACH_CSC                CSC                     3159
+gira_knxip_router      MACH_GIRA_KNXIP_ROUTER  GIRA_KNXIP_ROUTER       3160
+t20                    MACH_T20                T20                     3161
+hdmini                 MACH_HDMINI             HDMINI                  3162
+sciphone_g2            MACH_SCIPHONE_G2        SCIPHONE_G2             3163
+express                        MACH_EXPRESS            EXPRESS                 3164
+express_kt             MACH_EXPRESS_KT         EXPRESS_KT              3165
+maximasp               MACH_MAXIMASP           MAXIMASP                3166
+nitrogen_imx51         MACH_NITROGEN_IMX51     NITROGEN_IMX51          3167
+nitrogen_imx53         MACH_NITROGEN_IMX53     NITROGEN_IMX53          3168
+sunfire                        MACH_SUNFIRE            SUNFIRE                 3169
+arowana                        MACH_AROWANA            AROWANA                 3170
+tegra_daytona          MACH_TEGRA_DAYTONA      TEGRA_DAYTONA           3171
+tegra_swordfish                MACH_TEGRA_SWORDFISH    TEGRA_SWORDFISH         3172
+edison                 MACH_EDISON             EDISON                  3173
+svp8500v1              MACH_SVP8500V1          SVP8500V1               3174
+svp8500v2              MACH_SVP8500V2          SVP8500V2               3175
+svp5500                        MACH_SVP5500            SVP5500                 3176
+b5500                  MACH_B5500              B5500                   3177
+s5500                  MACH_S5500              S5500                   3178
+icon                   MACH_ICON               ICON                    3179
+elephant               MACH_ELEPHANT           ELEPHANT                3180
+msm8x60_fusion         MACH_MSM8X60_FUSION     MSM8X60_FUSION          3181
+shooter                        MACH_SHOOTER            SHOOTER                 3182
+spade_lte              MACH_SPADE_LTE          SPADE_LTE               3183
+philhwani              MACH_PHILHWANI          PHILHWANI               3184
+gsncomm                        MACH_GSNCOMM            GSNCOMM                 3185
+strasbourg_a2          MACH_STRASBOURG_A2      STRASBOURG_A2           3186
+mmm                    MACH_MMM                MMM                     3187
+davinci_dm365_bv       MACH_DAVINCI_DM365_BV   DAVINCI_DM365_BV        3188
+ag5evm                 MACH_AG5EVM             AG5EVM                  3189
+sc575plc               MACH_SC575PLC           SC575PLC                3190
+sc575hmi               MACH_SC575IPC           SC575IPC                3191
+omap3_tdm3730          MACH_OMAP3_TDM3730      OMAP3_TDM3730           3192
+g7                     MACH_G7                 G7                      3193
+top9000_eval           MACH_TOP9000_EVAL       TOP9000_EVAL            3194
+top9000_su             MACH_TOP9000_SU         TOP9000_SU              3195
+utm300                 MACH_UTM300             UTM300                  3196
+tsunagi                        MACH_TSUNAGI            TSUNAGI                 3197
+ts75xx                 MACH_TS75XX             TS75XX                  3198
+msm8x60_fusn_ffa       MACH_MSM8X60_FUSN_FFA   MSM8X60_FUSN_FFA        3199
+ts47xx                 MACH_TS47XX             TS47XX                  3200
+da850_k5               MACH_DA850_K5           DA850_K5                3201
+ax502                  MACH_AX502              AX502                   3202
+igep0032               MACH_IGEP0032           IGEP0032                3203
+antero                 MACH_ANTERO             ANTERO                  3204
+synergy                        MACH_SYNERGY            SYNERGY                 3205
+ics_if_voip            MACH_ICS_IF_VOIP        ICS_IF_VOIP             3206
+wlf_cragg_6410         MACH_WLF_CRAGG_6410     WLF_CRAGG_6410          3207
+punica                 MACH_PUNICA             PUNICA                  3208
+sbc_nt250              MACH_SBC_NT250          SBC_NT250               3209
+mx27_wmultra           MACH_MX27_WMULTRA       MX27_WMULTRA            3210
+mackerel               MACH_MACKEREL           MACKEREL                3211
+fa9x27                 MACH_FA9X27             FA9X27                  3213
+ns2816tb               MACH_NS2816TB           NS2816TB                3214
+ns2816_ntpad           MACH_NS2816_NTPAD       NS2816_NTPAD            3215
+ns2816_ntnb            MACH_NS2816_NTNB        NS2816_NTNB             3216
+kaen                   MACH_KAEN               KAEN                    3217
+nv1000                 MACH_NV1000             NV1000                  3218
+nuc950ts               MACH_NUC950TS           NUC950TS                3219
+nokia_rm680            MACH_NOKIA_RM680        NOKIA_RM680             3220
+ast2200                        MACH_AST2200            AST2200                 3221
+lead                   MACH_LEAD               LEAD                    3222
+unino1                 MACH_UNINO1             UNINO1                  3223
+greeco                 MACH_GREECO             GREECO                  3224
+verdi                  MACH_VERDI              VERDI                   3225
+dm6446_adbox           MACH_DM6446_ADBOX       DM6446_ADBOX            3226
+quad_salsa             MACH_QUAD_SALSA         QUAD_SALSA              3227
+abb_gma_1_1            MACH_ABB_GMA_1_1        ABB_GMA_1_1             3228
+svcid                  MACH_SVCID              SVCID                   3229
+msm8960_sim            MACH_MSM8960_SIM        MSM8960_SIM             3230
+msm8960_rumi3          MACH_MSM8960_RUMI3      MSM8960_RUMI3           3231
+icon_g                 MACH_ICON_G             ICON_G                  3232
+mb3                    MACH_MB3                MB3                     3233
+gsia18s                        MACH_GSIA18S            GSIA18S                 3234
+pivicc                 MACH_PIVICC             PIVICC                  3235
+pcm048                 MACH_PCM048             PCM048                  3236
+dds                    MACH_DDS                DDS                     3237
+chalten_xa1            MACH_CHALTEN_XA1        CHALTEN_XA1             3238
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 7f217b3a50a806b7347f991b588397011aa3388e..2e9d78d21fd36f9648286b2eb46df84beb4c9816 100644 (file)
@@ -22,7 +22,8 @@ config SUPERH
        select HAVE_SPARSE_IRQ
        select RTC_LIB
        select GENERIC_ATOMIC64
-       select GENERIC_HARDIRQS_NO_DEPRECATED
+       # Support the deprecated APIs until MFD and GPIOLIB catch up.
+       select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB
        help
          The SuperH is a RISC processor targeted for use in embedded systems
          and consumer electronics; it was also used in the Sega Dreamcast
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 903cd618eb740606853662d23765a694044e586c..d6741fca89a4f2d42b763d9789c5b81dc574988e 100644 (file)
 #define __NR_sendmsg           355
 #define __NR_recvmsg           356
 #define __NR_recvmmsg          357
+#define __NR_accept4           358
 
-#define NR_syscalls 358
+#define NR_syscalls 359
 
 #ifdef __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 e872e81add8a96ed12709964768a699f8a50306d..6fc347ebe59dfe0a356fe4d2d4f31ea52fa69206 100644 (file)
@@ -375,3 +375,4 @@ ENTRY(sys_call_table)
        .long sys_sendmsg               /* 355 */
        .long sys_recvmsg
        .long sys_recvmmsg
+       .long sys_accept4
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 81cd43432dc0ea5027eb0757ae2e27e2b13c5358..47eaafad15ceb63c8de66a8ef573d8fed32a714d 100644 (file)
@@ -39,7 +39,7 @@ struct linux_dev_v2_funcs {
        int (*v2_dev_open)(char *devpath);
        void (*v2_dev_close)(int d);
        int (*v2_dev_read)(int d, char *buf, int nbytes);
-       int (*v2_dev_write)(int d, char *buf, int nbytes);
+       int (*v2_dev_write)(int d, const char *buf, int nbytes);
        int (*v2_dev_seek)(int d, int hi, int lo);
 
        /* Never issued (multistage load support) */
index 51296a6f5005389877ca17c234f670fa71a3f8c0..9e5c64084b865781ca6782ced49b670ae35a5490 100644 (file)
@@ -60,25 +60,6 @@ extern char *prom_getbootargs(void);
 extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
 extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
 
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
@@ -121,19 +102,8 @@ extern int prom_getrev(void);
 /* Get the prom firmware revision. */
 extern int prom_getprev(void);
 
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
@@ -238,7 +208,6 @@ extern int prom_node_has_property(phandle node, char *property);
 extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
                        int value_size);
 
-extern phandle prom_pathtoinode(char *path);
 extern phandle prom_inst2pkg(int);
 
 /* Dorking with Bus ranges... */
index c9cc078e3e31531522fe5d531abcb0b72a1980b2..8cd0df34e82b86ada58f1399a8dab12a260adacb 100644 (file)
@@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack);
 /* Boot argument acquisition, returns the boot command line string. */
 extern char *prom_getbootargs(void);
 
-/* Device utilities. */
-
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(const char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
@@ -109,33 +88,14 @@ extern void prom_halt(void) __attribute__ ((noreturn));
 /* Halt and power-off the machine. */
 extern void prom_halt_power_off(void) __attribute__ ((noreturn));
 
-/* Set the PROM 'sync' callback function to the passed function pointer.
- * When the user gives the 'sync' command at the prom prompt while the
- * kernel is still active, the prom will call this routine.
- *
- */
-typedef int (*callback_func_t)(long *cmd);
-extern void prom_setcallback(callback_func_t func_ptr);
-
 /* Acquire the IDPROM of the root node in the prom device tree.  This
  * gets passed a buffer where you would like it stuffed.  The return value
  * is the format type of this idprom or 0xff on error.
  */
 extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
 
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
@@ -279,9 +239,7 @@ extern phandle prom_finddevice(const char *name);
 extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
                        int value_size);
 
-extern phandle prom_pathtoinode(const char *path);
 extern phandle prom_inst2pkg(int);
-extern int prom_service_exists(const char *service_name);
 extern void prom_sun4v_guest_soft_state(void);
 
 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
index 2d51527d810fc811531dae33c4bafc281b47d924..f01c42661ee51283183e6b6588297d20a78ec392 100644 (file)
@@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
        if (leon3_gptimer_regs && leon3_irqctrl_regs) {
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
-                                     (((1000000 / 100) - 1)));
+                                     (((1000000 / HZ) - 1)));
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
 
 #ifdef CONFIG_SMP
@@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
                }
 
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1)));
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1)));
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
 # endif
 
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 1b8c073adb44fe341b883f87865b28531d61b95f..816c0fa12dc0f546b94b58a728a24197adb48d22 100644 (file)
@@ -6,7 +6,6 @@ ccflags := -Werror
 
 lib-y                 := bootstr_$(BITS).o
 lib-$(CONFIG_SPARC32) += devmap.o
-lib-y                 += devops_$(BITS).o
 lib-y                 += init_$(BITS).o
 lib-$(CONFIG_SPARC32) += memory.o
 lib-y                 += misc_$(BITS).o
index 5340264b78f57c79dcd4f031d8348d31e9df1100..48863108a44ce6af379436c7f32ba2063e39a3f2 100644 (file)
 
 extern void restore_current(void);
 
-/* Non blocking get character from console input device, returns -1
- * if no input was taken.  This can be used for polling.
- */
-int
-prom_nbgetchar(void)
-{
-       static char inc;
-       int i = -1;
-       unsigned long flags;
-
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               i = (*(romvec->pv_nbgetchar))();
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) {
-                       i = inc;
-               } else {
-                       i = -1;
-               }
-               break;
-       default:
-               i = -1;
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-       return i; /* Ugh, we could spin forever on unsupported proms ;( */
-}
-
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
-int
-prom_nbputchar(char c)
+static int prom_nbputchar(const char *buf)
 {
-       static char outc;
        unsigned long flags;
        int i = -1;
 
        spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
-               i = (*(romvec->pv_nbputchar))(c);
+               i = (*(romvec->pv_nbputchar))(*buf);
                break;
        case PROM_V2:
        case PROM_V3:
-               outc = c;
-               if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1)
+               if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
+                                                         buf, 0x1) == 1)
                        i = 0;
-               else
-                       i = -1;
                break;
        default:
-               i = -1;
                break;
        };
        restore_current();
@@ -80,18 +43,14 @@ prom_nbputchar(char c)
        return i; /* Ugh, we could spin forever on unsupported proms ;( */
 }
 
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_console_write_buf(const char *buf, int len)
 {
-       int character;
-       while((character = prom_nbgetchar()) == -1) ;
-       return (char) character;
+       while (len) {
+               int n = prom_nbputchar(buf);
+               if (n)
+                       continue;
+               len--;
+               buf++;
+       }
 }
 
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
-{
-       while(prom_nbputchar(c) == -1) ;
-}
index 10322dc2f557a22d5befcc17dd4a27d8b6604f89..ed39e75828bd1eb6057f192d052ab88f5b943ddd 100644 (file)
 
 extern int prom_stdin, prom_stdout;
 
-/* Non blocking get character from console input device, returns -1
- * if no input was taken.  This can be used for polling.
- */
-inline int
-prom_nbgetchar(void)
-{
-       unsigned long args[7];
-       char inc;
-
-       args[0] = (unsigned long) "read";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) prom_stdin;
-       args[4] = (unsigned long) &inc;
-       args[5] = 1;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-
-       if (args[6] == 1)
-               return inc;
-       return -1;
-}
-
-/* Non blocking put character to console device, returns -1 if
- * unsuccessful.
- */
-inline int
-prom_nbputchar(char c)
+static int __prom_console_write_buf(const char *buf, int len)
 {
        unsigned long args[7];
-       char outc;
-       
-       outc = c;
+       int ret;
 
        args[0] = (unsigned long) "write";
        args[1] = 3;
        args[2] = 1;
        args[3] = (unsigned int) prom_stdout;
-       args[4] = (unsigned long) &outc;
-       args[5] = 1;
+       args[4] = (unsigned long) buf;
+       args[5] = (unsigned int) len;
        args[6] = (unsigned long) -1;
 
        p1275_cmd_direct(args);
 
-       if (args[6] == 1)
-               return 0;
-       else
+       ret = (int) args[6];
+       if (ret < 0)
                return -1;
+       return ret;
 }
 
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
-{
-       int character;
-       while((character = prom_nbgetchar()) == -1) ;
-       return (char) character;
-}
-
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
+void prom_console_write_buf(const char *buf, int len)
 {
-       prom_nbputchar(c);
-}
-
-void
-prom_puts(const char *s, int len)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "write";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) prom_stdout;
-       args[4] = (unsigned long) s;
-       args[5] = len;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
+       while (len) {
+               int n = __prom_console_write_buf(buf, len);
+               if (n < 0)
+                       continue;
+               len -= n;
+               buf += len;
+       }
 }
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c
deleted file mode 100644 (file)
index 9c5d468..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * devops.c:  Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-extern void restore_current(void);
-
-/* Open the device described by the string 'dstr'.  Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns -1 on failure.
- */
-int
-prom_devopen(char *dstr)
-{
-       int handle;
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               handle = (*(romvec->pv_v0devops.v0_devopen))(dstr);
-               if(handle == 0) handle = -1;
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr);
-               break;
-       default:
-               handle = -1;
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-
-       return handle;
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               (*(romvec->pv_v0devops.v0_devclose))(dhandle);
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               (*(romvec->pv_v2devops.v2_dev_close))(dhandle);
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-       return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo);
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo);
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-}
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c
deleted file mode 100644 (file)
index a017119..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * devops.c:  Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-/* Open the device described by the string 'dstr'.  Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns 0 on failure.
- */
-int
-prom_devopen(const char *dstr)
-{
-       unsigned long args[5];
-
-       args[0] = (unsigned long) "open";
-       args[1] = 1;
-       args[2] = 1;
-       args[3] = (unsigned long) dstr;
-       args[4] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-
-       return (int) args[4];
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
-       unsigned long args[4];
-
-       args[0] = (unsigned long) "close";
-       args[1] = 1;
-       args[2] = 0;
-       args[3] = (unsigned int) dhandle;
-
-       p1275_cmd_direct(args);
-
-       return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "seek";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) dhandle;
-       args[4] = seekhi;
-       args[5] = seeklo;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-}
index d24bc44e361ee20b654960cc7784176670705da6..e4f31d4d3715cc5c27752633ba58e052e853a956 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/system.h>
 #include <asm/ldc.h>
 
-int prom_service_exists(const char *service_name)
+static int prom_service_exists(const char *service_name)
 {
        unsigned long args[5];
 
@@ -150,20 +150,6 @@ void prom_halt_power_off(void)
        prom_halt();
 }
 
-/* Set prom sync handler to call function 'funcp'. */
-void prom_setcallback(callback_func_t funcp)
-{
-       unsigned long args[5];
-       if (!funcp)
-               return;
-       args[0] = (unsigned long) "set-callback";
-       args[1] = 1;
-       args[2] = 1;
-       args[3] = (unsigned long) funcp;
-       args[4] = (unsigned long) -1;
-       p1275_cmd_direct(args);
-}
-
 /* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
  * format type.  'num_bytes' is the number of bytes that your idbuf
  * has space for.  Returns 0xff on error.
index ca869266b9f3d0106e60d7b8c28f5cdcf614826b..d9682f06b3b056c7862ec7cda4214a95ab213a03 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/compiler.h>
+#include <linux/spinlock.h>
 
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 
+#define CONSOLE_WRITE_BUF_SIZE 1024
+
 static char ppbuf[1024];
+static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
+static DEFINE_RAW_SPINLOCK(console_write_lock);
 
 void notrace prom_write(const char *buf, unsigned int n)
 {
-       char ch;
+       unsigned int dest_len;
+       unsigned long flags;
+       char *dest;
+
+       dest = console_write_buf;
+       raw_spin_lock_irqsave(&console_write_lock, flags);
 
-       while (n != 0) {
-               --n;
-               if ((ch = *buf++) == '\n')
-                       prom_putchar('\r');
-               prom_putchar(ch);
+       dest_len = 0;
+       while (n-- != 0) {
+               char ch = *buf++;
+               if (ch == '\n') {
+                       *dest++ = '\r';
+                       dest_len++;
+               }
+               *dest++ = ch;
+               dest_len++;
+               if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) {
+                       prom_console_write_buf(console_write_buf, dest_len);
+                       dest = console_write_buf;
+                       dest_len = 0;
+               }
        }
+       if (dest_len)
+               prom_console_write_buf(console_write_buf, dest_len);
+
+       raw_spin_unlock_irqrestore(&console_write_lock, flags);
 }
 
 void notrace prom_printf(const char *fmt, ...)
index 63e08e149774fc6a0a30fcd9228abb83f434aae7..535e2e69ac1d8287470356218511c25af6be7a8c 100644 (file)
@@ -342,19 +342,3 @@ phandle prom_inst2pkg(int inst)
        if (node == -1) return 0;
        return node;
 }
-
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(char *path)
-{
-       phandle node;
-       int inst;
-       
-       inst = prom_devopen (path);
-       if (inst == -1) return 0;
-       node = prom_inst2pkg (inst);
-       prom_devclose (inst);
-       if (node == -1) return 0;
-       return node;
-}
index 691be68932f84cf7d804b2a7ce6720fceeedc447..d93660048376c9d9bf4478720a6825e9e7b117ed 100644 (file)
@@ -374,24 +374,6 @@ inline phandle prom_inst2pkg(int inst)
        return node;
 }
 
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(const char *path)
-{
-       phandle node;
-       int inst;
-
-       inst = prom_devopen (path);
-       if (inst == 0)
-               return 0;
-       node = prom_inst2pkg(inst);
-       prom_devclose(inst);
-       if (node == -1)
-               return 0;
-       return node;
-}
-
 int prom_ihandle2path(int handle, char *buffer, int bufsize)
 {
        unsigned long args[7];
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 e8327686d3c55d86adb19b3c9c83bc9869e5c3cf..e330da21b84f0636751b7e18e921ecff9cc31f55 100644 (file)
@@ -21,7 +21,7 @@ config X86
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_IDE
        select HAVE_OPROFILE
-       select HAVE_PERF_EVENTS if (!M386 && !M486)
+       select HAVE_PERF_EVENTS
        select HAVE_IRQ_WORK
        select HAVE_IOREMAP_PROT
        select HAVE_KPROBES
index cbcc8d8ea93a9144471fede4aeca15bdb4780203..7a6e68e4f748fc2db4af59f42d4c1caad9460060 100644 (file)
@@ -10,6 +10,7 @@
  * by the Free Software Foundation.
  */
 
+#include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.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 18e3b8a8709f9def52af32b8f27b05afbdd7a4ae..ef9975812c77f0702cc9fb2a1fb616b9cb1b8053 100644 (file)
@@ -824,27 +824,27 @@ static __always_inline void arch_spin_unlock(struct arch_spinlock *lock)
 #define __PV_IS_CALLEE_SAVE(func)                      \
        ((struct paravirt_callee_save) { func })
 
-static inline unsigned long arch_local_save_flags(void)
+static inline notrace unsigned long arch_local_save_flags(void)
 {
        return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl);
 }
 
-static inline void arch_local_irq_restore(unsigned long f)
+static inline notrace void arch_local_irq_restore(unsigned long f)
 {
        PVOP_VCALLEE1(pv_irq_ops.restore_fl, f);
 }
 
-static inline void arch_local_irq_disable(void)
+static inline notrace void arch_local_irq_disable(void)
 {
        PVOP_VCALLEE0(pv_irq_ops.irq_disable);
 }
 
-static inline void arch_local_irq_enable(void)
+static inline notrace void arch_local_irq_enable(void)
 {
        PVOP_VCALLEE0(pv_irq_ops.irq_enable);
 }
 
-static inline unsigned long arch_local_irq_save(void)
+static inline notrace unsigned long arch_local_irq_save(void)
 {
        unsigned long f;
 
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 cefd6942f0e9198e260559c436f443e861ffb011..62f6e1e55b90d7f9a2bc460e73ba8895da23c4ff 100644 (file)
 #include <linux/nmi.h>
 #include <linux/module.h>
 
-/* For reliability, we're prepared to waste bits here. */
-static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
-
 u64 hw_nmi_get_sample_period(void)
 {
        return (u64)(cpu_khz) * 1000 * 60;
 }
 
 #ifdef ARCH_HAS_NMI_WATCHDOG
+
+/* For reliability, we're prepared to waste bits here. */
+static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
+
 void arch_trigger_all_cpu_backtrace(void)
 {
        int i;
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 ed6310183efb4337de7489362b350f81031ca2c8..6d75b9145b13f0e68a106acd76b0d458c827d099 100644 (file)
@@ -381,6 +381,20 @@ static void release_pmc_hardware(void) {}
 
 #endif
 
+static bool check_hw_exists(void)
+{
+       u64 val, val_new = 0;
+       int ret = 0;
+
+       val = 0xabcdUL;
+       ret |= checking_wrmsrl(x86_pmu.perfctr, val);
+       ret |= rdmsrl_safe(x86_pmu.perfctr, &val_new);
+       if (ret || val != val_new)
+               return false;
+
+       return true;
+}
+
 static void reserve_ds_buffers(void);
 static void release_ds_buffers(void);
 
@@ -1372,6 +1386,12 @@ void __init init_hw_perf_events(void)
 
        pmu_check_apic();
 
+       /* sanity check that the hardware exists or is emulated */
+       if (!check_hw_exists()) {
+               pr_cont("Broken PMU hardware detected, software events only.\n");
+               return;
+       }
+
        pr_cont("%s PMU driver.\n", x86_pmu.name);
 
        if (x86_pmu.quirks)
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 fe2690d71c0c9f1d27be243f2ca12183a6705357..e3ba417e869766bb258ef489aa389f4933abf2a3 100644 (file)
@@ -295,6 +295,7 @@ ENDPROC(native_usergs_sysret64)
        .endm
 
 /* save partial stack frame */
+       .pushsection .kprobes.text, "ax"
 ENTRY(save_args)
        XCPT_FRAME
        cld
@@ -334,6 +335,7 @@ ENTRY(save_args)
        ret
        CFI_ENDPROC
 END(save_args)
+       .popsection
 
 ENTRY(save_rest)
        PARTIAL_FRAME 1 REST_SKIP+8
index ff15c9dcc25de8be8144fd4d15f1dfd3069314e4..42c59425450727284615b2a920611e21047ce715 100644 (file)
@@ -433,6 +433,10 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
        dr6_p = (unsigned long *)ERR_PTR(args->err);
        dr6 = *dr6_p;
 
+       /* If it's a single step, TRAP bits are random */
+       if (dr6 & DR_STEP)
+               return NOTIFY_DONE;
+
        /* Do an early return if no trap bits are set in DR6 */
        if ((dr6 & DR_TRAP_BITS) == 0)
                return NOTIFY_DONE;
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 f20d6a789d484591e9fdb5642fa893c233c2b9b0..0c8b64a16484721308587c7a6b635344a9144a1e 100644 (file)
@@ -250,6 +250,14 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
        int ret, rw;
        unsigned int dxfer_len;
        void *dxferp = NULL;
+       struct bsg_class_device *bcd = &q->bsg_dev;
+
+       /* if the LLD has been removed then the bsg_unregister_queue will
+        * eventually be called and the class_dev was freed, so we can no
+        * longer use this request_queue. Return no such address.
+        */
+       if (!bcd->class_dev)
+               return ERR_PTR(-ENXIO);
 
        dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp,
                hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp,
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 fefa9a4967083208ff880d5a6b31139042661827..9049d460fa890fd45e3e31c1aa8ca9ed080e9f81 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 ba9afeaa23acfb676021c86432fd89b45f8ba5cf..25d3aaebc10d4d86238c0af67bcb01976b6dcd65 100644 (file)
@@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = {
        .release = single_release,
 };
 #endif
-static int get_ac_property(struct power_supply *psy,
-                          enum power_supply_property psp,
-                          union power_supply_propval *val)
-{
-       struct acpi_ac *ac = to_acpi_ac(psy);
-       switch (psp) {
-       case POWER_SUPPLY_PROP_ONLINE:
-               val->intval = ac->state;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
 
-static enum power_supply_property ac_props[] = {
-       POWER_SUPPLY_PROP_ONLINE,
-};
 /* --------------------------------------------------------------------------
                                AC Adapter Management
    -------------------------------------------------------------------------- */
@@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
        return 0;
 }
 
+/* --------------------------------------------------------------------------
+                            sysfs I/F
+   -------------------------------------------------------------------------- */
+static int get_ac_property(struct power_supply *psy,
+                          enum power_supply_property psp,
+                          union power_supply_propval *val)
+{
+       struct acpi_ac *ac = to_acpi_ac(psy);
+
+       if (!ac)
+               return -ENODEV;
+
+       if (acpi_ac_get_state(ac))
+               return -ENODEV;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               val->intval = ac->state;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
+
 #ifdef CONFIG_ACPI_PROCFS_POWER
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
index 1211c03149e8c7c258fee89dd1109e1e6b901c26..5850d320404c35b9c7318eb0619ae54c7e32a30b 100644 (file)
@@ -86,7 +86,7 @@ static struct erst_erange {
  * It is used to provide exclusive accessing for ERST Error Log
  * Address Range too.
  */
-static DEFINE_SPINLOCK(erst_lock);
+static DEFINE_RAW_SPINLOCK(erst_lock);
 
 static inline int erst_errno(int command_status)
 {
@@ -421,9 +421,9 @@ ssize_t erst_get_record_count(void)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        count = __erst_get_record_count();
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return count;
 }
@@ -456,9 +456,9 @@ int erst_get_next_record_id(u64 *record_id)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        rc = __erst_get_next_record_id(record_id);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
@@ -624,17 +624,17 @@ int erst_write(const struct cper_record_header *record)
                return -EINVAL;
 
        if (erst_erange.attr & ERST_RANGE_NVRAM) {
-               if (!spin_trylock_irqsave(&erst_lock, flags))
+               if (!raw_spin_trylock_irqsave(&erst_lock, flags))
                        return -EBUSY;
                rc = __erst_write_to_nvram(record);
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return rc;
        }
 
        if (record->record_length > erst_erange.size)
                return -EINVAL;
 
-       if (!spin_trylock_irqsave(&erst_lock, flags))
+       if (!raw_spin_trylock_irqsave(&erst_lock, flags))
                return -EBUSY;
        memcpy(erst_erange.vaddr, record, record->record_length);
        rcd_erange = erst_erange.vaddr;
@@ -642,7 +642,7 @@ int erst_write(const struct cper_record_header *record)
        memcpy(&rcd_erange->persistence_information, "ER", 2);
 
        rc = __erst_write_to_storage(0);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
@@ -696,9 +696,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        len = __erst_read(record_id, record, buflen);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
        return len;
 }
 EXPORT_SYMBOL_GPL(erst_read);
@@ -719,20 +719,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        rc = __erst_get_next_record_id(&record_id);
        if (rc) {
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return rc;
        }
        /* no more record */
        if (record_id == APEI_ERST_INVALID_RECORD_ID) {
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return 0;
        }
 
        len = __erst_read(record_id, record, buflen);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return len;
 }
@@ -746,12 +746,12 @@ int erst_clear(u64 record_id)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        if (erst_erange.attr & ERST_RANGE_NVRAM)
                rc = __erst_clear_from_nvram(record_id);
        else
                rc = __erst_clear_from_storage(record_id);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
index 1a3508a7fe03f157c2e0144727bbeb5c244d2a46..daa7bc63f1d4bad00fd988ddcce3681fdc74f804 100644 (file)
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable);
 
 /* HEST table parsing */
 
-static struct acpi_table_hest *hest_tab;
+static struct acpi_table_hest *__read_mostly hest_tab;
 
-static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
+static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
        [ACPI_HEST_TYPE_IA32_CHECK] = -1,       /* need further calculation */
        [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
        [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi),
@@ -126,7 +126,7 @@ struct ghes_arr {
        unsigned int count;
 };
 
-static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
 {
        int *count = data;
 
@@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
        return 0;
 }
 
-static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
 {
        struct platform_device *ghes_dev;
        struct ghes_arr *ghes_arr = data;
@@ -165,7 +165,7 @@ err:
        return rc;
 }
 
-static int hest_ghes_dev_register(unsigned int ghes_count)
+static int __init hest_ghes_dev_register(unsigned int ghes_count)
 {
        int rc, i;
        struct ghes_arr ghes_arr;
index 95649d373071ac93d14bbbb478db1ab4a8cdb801..9fb9d5ac939db1c071c4cdcaa7fba49364236e25 100644 (file)
@@ -130,6 +130,8 @@ struct acpi_battery {
        unsigned long flags;
 };
 
+static int acpi_battery_update(struct acpi_battery *battery);
+
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
 
 inline int acpi_battery_present(struct acpi_battery *battery)
@@ -184,6 +186,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
        int ret = 0;
        struct acpi_battery *battery = to_acpi_battery(psy);
 
+       if (acpi_battery_update(battery))
+               return -ENODEV;
+
        if (acpi_battery_present(battery)) {
                /* run battery update only if it is present */
                acpi_battery_get_state(battery);
index 372ff80b7b0c93f88f6f2ea9e100c0fdd2aaf6bf..302b31ed31f1ea099faa48b989114e9c99dc1485 100644 (file)
@@ -934,6 +934,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
        ec_flag_msi, "MSI hardware", {
        DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
        {
+       ec_flag_msi, "MSI hardware", {
+       DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
+       {
        ec_validate_ecdt, "ASUS hardware", {
        DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
        {},
index 966feddf6b1ba29457fde294223018ad23666e39..055d7b701fff16d18fe5de5ea243ba8ec477e3ec 100644 (file)
@@ -110,9 +110,6 @@ struct acpi_ioremap {
 static LIST_HEAD(acpi_ioremaps);
 static DEFINE_SPINLOCK(acpi_ioremap_lock);
 
-#define        OSI_STRING_LENGTH_MAX 64        /* arbitrary */
-static char osi_setup_string[OSI_STRING_LENGTH_MAX];
-
 static void __init acpi_osi_setup_late(void);
 
 /*
@@ -152,8 +149,7 @@ static struct osi_linux {
        unsigned int    enable:1;
        unsigned int    dmi:1;
        unsigned int    cmdline:1;
-       unsigned int    known:1;
-} osi_linux = { 0, 0, 0, 0};
+} osi_linux = {0, 0, 0};
 
 static u32 acpi_osi_handler(acpi_string interface, u32 supported)
 {
@@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str)
 
 __setup("acpi_os_name=", acpi_os_name_setup);
 
+#define        OSI_STRING_LENGTH_MAX 64        /* arbitrary */
+#define        OSI_STRING_ENTRIES_MAX 16       /* arbitrary */
+
+struct osi_setup_entry {
+       char string[OSI_STRING_LENGTH_MAX];
+       bool enable;
+};
+
+static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
+
+void __init acpi_osi_setup(char *str)
+{
+       struct osi_setup_entry *osi;
+       bool enable = true;
+       int i;
+
+       if (!acpi_gbl_create_osi_method)
+               return;
+
+       if (str == NULL || *str == '\0') {
+               printk(KERN_INFO PREFIX "_OSI method disabled\n");
+               acpi_gbl_create_osi_method = FALSE;
+               return;
+       }
+
+       if (*str == '!') {
+               str++;
+               enable = false;
+       }
+
+       for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+               osi = &osi_setup_entries[i];
+               if (!strcmp(osi->string, str)) {
+                       osi->enable = enable;
+                       break;
+               } else if (osi->string[0] == '\0') {
+                       osi->enable = enable;
+                       strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
+                       break;
+               }
+       }
+}
+
 static void __init set_osi_linux(unsigned int enable)
 {
-       if (osi_linux.enable != enable) {
+       if (osi_linux.enable != enable)
                osi_linux.enable = enable;
-               printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
-                       enable ? "Add": "Delet");
-       }
 
        if (osi_linux.enable)
                acpi_osi_setup("Linux");
@@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable)
 
 static void __init acpi_cmdline_osi_linux(unsigned int enable)
 {
-       osi_linux.cmdline = 1;  /* cmdline set the default */
+       osi_linux.cmdline = 1;  /* cmdline set the default and override DMI */
+       osi_linux.dmi = 0;
        set_osi_linux(enable);
 
        return;
@@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable)
 
 void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
 {
-       osi_linux.dmi = 1;      /* DMI knows that this box asks OSI(Linux) */
-
        printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
 
        if (enable == -1)
                return;
 
-       osi_linux.known = 1;    /* DMI knows which OSI(Linux) default needed */
-
+       osi_linux.dmi = 1;      /* DMI knows that this box asks OSI(Linux) */
        set_osi_linux(enable);
 
        return;
@@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
  */
 static void __init acpi_osi_setup_late(void)
 {
-       char *str = osi_setup_string;
+       struct osi_setup_entry *osi;
+       char *str;
+       int i;
+       acpi_status status;
 
-       if (*str == '\0')
-               return;
+       for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+               osi = &osi_setup_entries[i];
+               str = osi->string;
 
-       if (!strcmp("!Linux", str)) {
-               acpi_cmdline_osi_linux(0);      /* !enable */
-       } else if (*str == '!') {
-               if (acpi_remove_interface(++str) == AE_OK)
-                       printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
-       } else if (!strcmp("Linux", str)) {
-               acpi_cmdline_osi_linux(1);      /* enable */
-       } else {
-               if (acpi_install_interface(str) == AE_OK)
-                       printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+               if (*str == '\0')
+                       break;
+               if (osi->enable) {
+                       status = acpi_install_interface(str);
+
+                       if (ACPI_SUCCESS(status))
+                               printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+               } else {
+                       status = acpi_remove_interface(str);
+
+                       if (ACPI_SUCCESS(status))
+                               printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+               }
        }
 }
 
-int __init acpi_osi_setup(char *str)
+static int __init osi_setup(char *str)
 {
-       if (str == NULL || *str == '\0') {
-               printk(KERN_INFO PREFIX "_OSI method disabled\n");
-               acpi_gbl_create_osi_method = FALSE;
-       } else {
-               strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
-       }
+       if (str && !strcmp("Linux", str))
+               acpi_cmdline_osi_linux(1);
+       else if (str && !strcmp("!Linux", str))
+               acpi_cmdline_osi_linux(0);
+       else
+               acpi_osi_setup(str);
 
        return 1;
 }
 
-__setup("acpi_osi=", acpi_osi_setup);
+__setup("acpi_osi=", osi_setup);
 
 /* enable serialization to combat AE_ALREADY_EXISTS errors */
 static int __init acpi_serialize_setup(char *str)
@@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void)
        return AE_OK;
 }
 
-acpi_status acpi_os_initialize1(void)
+acpi_status __init acpi_os_initialize1(void)
 {
        kacpid_wq = create_workqueue("kacpid");
        kacpi_notify_wq = create_workqueue("kacpi_notify");
index 67dedeed144cf82c8e13859e7222b976d0eebb2e..4c9c2fb5d98f9a14a67e8618b44dc6f2c642887b 100644 (file)
@@ -213,11 +213,13 @@ static int acpi_power_on(acpi_handle handle)
                                  resource->name));
        } else {
                result = __acpi_power_on(resource);
+               if (result)
+                       resource->ref_count--;
        }
 
        mutex_unlock(&resource->resource_lock);
 
-       return 0;
+       return result;
 }
 
 static int acpi_power_off_device(acpi_handle handle)
@@ -465,10 +467,12 @@ int acpi_power_transition(struct acpi_device *device, int state)
        struct acpi_handle_list *tl = NULL;     /* Target Resources */
        int i = 0;
 
-
        if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
                return -EINVAL;
 
+       if (device->power.state == state)
+               return 0;
+
        if ((device->power.state < ACPI_STATE_D0)
            || (device->power.state > ACPI_STATE_D3))
                return -ENODEV;
@@ -488,10 +492,6 @@ int acpi_power_transition(struct acpi_device *device, int state)
                        goto end;
        }
 
-       if (device->power.state == state) {
-               goto end;
-       }
-
        /*
         * Then we dereference all power resources used in the current list.
         */
index fde49b9b1d99ed04eaf4192473ff7ce3bb913fd6..79cb6533289456c4f43b92dda5d7059a27345afa 100644 (file)
@@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
        return 0;
 }
 
-static int acpi_thermal_cpufreq_increase(unsigned int cpu)
-{
-       return -ENODEV;
-}
-static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
-{
-       return -ENODEV;
-}
-
 #endif
 
 int acpi_processor_get_limit_info(struct acpi_processor *pr)
index 721d93b3ceee78c3b271f5f84ffe4fc795e435e1..febb153b5a68cf216fdd1b528ac44159e73abcba 100644 (file)
@@ -27,8 +27,6 @@
 
 static u8 sleep_states[ACPI_S_STATE_COUNT];
 
-static u32 acpi_target_sleep_state = ACPI_STATE_S0;
-
 static void acpi_sleep_tts_switch(u32 acpi_state)
 {
        union acpi_object in_arg = { ACPI_TYPE_INTEGER };
@@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state)
 }
 
 #ifdef CONFIG_ACPI_SLEEP
+static u32 acpi_target_sleep_state = ACPI_STATE_S0;
+
 /*
  * The ACPI specification wants us to save NVS memory regions during hibernation
  * and to restore them during the subsequent resume.  Windows does that also for
@@ -427,6 +427,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
                },
        },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-NW130D",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
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 46b94762125b0b179792948cbd47be8a9bc8448f..f9b983ae68777544f5cc986f3e0e4e3b1f074179 100644 (file)
@@ -154,7 +154,7 @@ static int __init adummy_init(void)
                err = -ENOMEM;
                goto out;
        }
-       atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
+       atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
        if (!atm_dev) {
                printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
                err = -ENODEV;
index a33896a482e6eb0e0dd964649b5b6d7d90e64858..ffe9b655292e148e929365fe5bd8cd1b86443411 100644 (file)
@@ -2244,7 +2244,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_
                goto out_reset;
        }
 
-       dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
+       dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1,
+                                        NULL);
        if (!dev->atm_dev) {
                PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
                err = -EINVAL;
index b9101818b47b4012d9c5589d7b8ffd672cb26fc7..2b464b631f22697ac5f177d371b94d5646683d8f 100644 (file)
@@ -366,7 +366,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result)
        if (!dev_data)
                return -ENOMEM;
 
-       dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
+       dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL);
        if (!dev) {
                kfree(dev_data);
                return itf == -1 ? -ENOMEM : -EBUSY;
index 97c5898cd76e894350dfcc3a444de9ce2d202e35..c495fae742008c6569da47d5c3ca91c7f5ad48b4 100644 (file)
@@ -2244,7 +2244,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev,
                    &zeroes);
                if (!cpu_zeroes) goto out1;
        }
-       dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL);
+       dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
        if (!dev) goto out2;
        pci_set_drvdata(pci_dev, dev);
        eni_dev->pci_dev = pci_dev;
index 5d86bb803e9493443659f49180b68c147066a166..7d912baf01d444c6adaaa943f87e107ead7441b6 100644 (file)
@@ -1911,7 +1911,7 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev,
                    fs_dev, sizeof (struct fs_dev));
        if (!fs_dev)
                goto err_out;
-       atm_dev = atm_dev_register("fs", &ops, -1, NULL);
+       atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL);
        if (!atm_dev)
                goto err_out_free_fs_dev;
   
index c8fc69c85a062f81029495e827ae615547f964e9..962c309b40c035bea03e751fd9531de6eb7df1e9 100644 (file)
@@ -2567,14 +2567,14 @@ release:
 
 
 static int __devinit
-fore200e_register(struct fore200e* fore200e)
+fore200e_register(struct fore200e* fore200e, struct device *parent)
 {
     struct atm_dev* atm_dev;
 
     DPRINTK(2, "device %s being registered\n", fore200e->name);
 
-    atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1,
-      NULL); 
+    atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
+                               -1, NULL);
     if (atm_dev == NULL) {
        printk(FORE200E "unable to register device %s\n", fore200e->name);
        return -ENODEV;
@@ -2594,9 +2594,9 @@ fore200e_register(struct fore200e* fore200e)
 
 
 static int __devinit
-fore200e_init(struct fore200e* fore200e)
+fore200e_init(struct fore200e* fore200e, struct device *parent)
 {
-    if (fore200e_register(fore200e) < 0)
+    if (fore200e_register(fore200e, parent) < 0)
        return -ENODEV;
     
     if (fore200e->bus->configure(fore200e) < 0)
@@ -2662,7 +2662,7 @@ static int __devinit fore200e_sba_probe(struct platform_device *op,
 
        sprintf(fore200e->name, "%s-%d", bus->model_name, index);
 
-       err = fore200e_init(fore200e);
+       err = fore200e_init(fore200e, &op->dev);
        if (err < 0) {
                fore200e_shutdown(fore200e);
                kfree(fore200e);
@@ -2740,7 +2740,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent
 
     sprintf(fore200e->name, "%s-%d", bus->model_name, index);
 
-    err = fore200e_init(fore200e);
+    err = fore200e_init(fore200e, &pci_dev->dev);
     if (err < 0) {
        fore200e_shutdown(fore200e);
        goto out_free;
index 801e8b6e9d1fee08dd1b3d091ff3739193ee98cc..6cf59bf281dc1b601884586b7d8651ea0ecbeaa7 100644 (file)
@@ -366,7 +366,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
                goto init_one_failure;
        }
 
-       atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL);
+       atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL);
        if (!atm_dev) {
                err = -ENODEV;
                goto init_one_failure;
index a95790452a685f3325ed64af5db2f2596f911236..24761e1d6642d7c6a2c7dcb6e8d4073c89f76c64 100644 (file)
@@ -2733,7 +2733,8 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_
        PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p",
               iobase, irq, membase);
 
-       dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL);
+       dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1,
+                                       NULL);
        if (!(dev->atm_dev)) {
                PRINTD(DBG_ERR, "failed to register Madge ATM adapter");
                err = -EINVAL;
index bce57328ddde9addf376fe550a768194c4173c9b..bfb7feee0400df5c8f9a13adc0cde06a053c2ac7 100644 (file)
@@ -3698,7 +3698,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
                goto err_out_iounmap;
        }
 
-       dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL);
+       dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1,
+                              NULL);
        if (!dev) {
                printk("%s: can't register atm device\n", card->name);
                err = -EIO;
index 9309d4724e1322effe4010042dc0a3136a432ebb..729254053758f0d3680ad67f52a32a07865f86b0 100644 (file)
@@ -3172,7 +3172,7 @@ static int __devinit ia_init_one(struct pci_dev *pdev,
                ret = -ENODEV;
                goto err_out_free_iadev;
        }
-       dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL);
        if (!dev) {
                ret = -ENOMEM;
                goto err_out_disable_dev;
index cbe15a86c6698b2044b45469fa57f8d199aca15e..a395c9aab146ec4f78d0b05767c81b04889c16ef 100644 (file)
@@ -2591,7 +2591,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci,
                return -ENOMEM;
        }
 
-       atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL);
        if (atmdev == NULL) {
                printk(KERN_ERR DEV_LABEL
                    ": couldn't register atm device!\n");
index 2f3516b7f118cd59e7b9156ba1b004a6caee6c86..6b313ee9231baa2cd37893ba26c5e4877462ba0a 100644 (file)
@@ -771,7 +771,8 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
        }
 
        /* Register device */
-       card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL);
+       card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
+                                       -1, NULL);
        if (card->atmdev == NULL) {
                printk("nicstar%d: can't register device.\n", i);
                error = 17;
index 2e08c996fd30a6156e8a0a19e46966824d3d89df..73fb1c4f4cd4e99f0b57df7977c22216a781e1e6 100644 (file)
@@ -166,7 +166,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id);
 static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
 static int list_vccs(int vci);
 static void release_vccs(struct atm_dev *dev);
-static int atm_init(struct solos_card *);
+static int atm_init(struct solos_card *, struct device *);
 static void atm_remove(struct solos_card *);
 static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
 static void solos_bh(unsigned long);
@@ -1210,7 +1210,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (db_firmware_upgrade)
                flash_upgrade(card, 3);
 
-       err = atm_init(card);
+       err = atm_init(card, &dev->dev);
        if (err)
                goto out_free_irq;
 
@@ -1233,7 +1233,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        return err;
 }
 
-static int atm_init(struct solos_card *card)
+static int atm_init(struct solos_card *card, struct device *parent)
 {
        int i;
 
@@ -1244,7 +1244,7 @@ static int atm_init(struct solos_card *card)
                skb_queue_head_init(&card->tx_queue[i]);
                skb_queue_head_init(&card->cli_queue[i]);
 
-               card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL);
+               card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL);
                if (!card->atmdev[i]) {
                        dev_err(&card->dev->dev, "Could not register ATM device %d\n", i);
                        atm_remove(card);
index 4e885d2da49c6f0b5899b9eb3d8d1a874e700ca3..624917902b656f249fd06b057090f0f9d7b97961 100644 (file)
@@ -1597,7 +1597,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev,
                goto out;
        }
 
-       dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
        if (!dev)
                goto out_free;
 
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 4f9e22f29138f1001dfca566ab3b04e176b6ae2e..657873e4328dbf05421b80e8d1231f27c5d3b369 100644 (file)
@@ -72,7 +72,7 @@ struct blk_shadow {
 static DEFINE_MUTEX(blkfront_mutex);
 static const struct block_device_operations xlvbd_block_fops;
 
-#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
+#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
 
 /*
  * We have one of these per vbd, whether ide, scsi or 'other'.  They
index 128cae4e8629465429cf271209f587b8e192b3ad..949ed09c6361130c30c3ebda1bc4db02b00fa4c2 100644 (file)
 static struct usb_device_id ath3k_table[] = {
        /* Atheros AR3011 */
        { USB_DEVICE(0x0CF3, 0x3000) },
+
+       /* Atheros AR3011 with sflash firmware*/
+       { USB_DEVICE(0x0CF3, 0x3002) },
+
        { }     /* Terminating entry */
 };
 
index ab3894f742c3002a90a98b89f116ab30c75cdb28..1da773f899a2708f1c151b892098ed3ddbaf79cf 100644 (file)
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = {
        /* Broadcom BCM2033 without firmware */
        { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
 
+       /* Atheros 3011 with sflash firmware */
+       { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
+
        /* Broadcom BCM2035 */
        { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
        { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -239,7 +242,8 @@ static void btusb_intr_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
@@ -323,7 +327,8 @@ static void btusb_bulk_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
@@ -412,7 +417,8 @@ static void btusb_isoc_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
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 e16c3fa8d2e3e3649a6cab79fb34db9323aae711..05117f1ad8674839331ddb7c473b4cfc739bbddd 100644 (file)
@@ -36,6 +36,7 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
 MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR);
 
 static struct cn_dev cdev;
 
index a8a84f4587f20d7437af9ce12932dbf8e92a4e1b..64b21f5cd740fc5dfa1d5f09b1a944ed1f661440 100644 (file)
@@ -1,8 +1,8 @@
 ifeq ($(CONFIG_DMADEVICES_DEBUG),y)
-       EXTRA_CFLAGS    += -DDEBUG
+       ccflags-y       += -DDEBUG
 endif
 ifeq ($(CONFIG_DMADEVICES_VDEBUG),y)
-       EXTRA_CFLAGS    += -DVERBOSE_DEBUG
+       ccflags-y       += -DVERBOSE_DEBUG
 endif
 
 obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
index a0f3e6a06e06532b3701ade73b110d823eec591f..ea0ee81cff53e266643140eb752ef3ba26289c6a 100644 (file)
@@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                        desc->lli.daddr = mem;
                        desc->lli.ctrla = ctrla
                                        | ATC_DST_WIDTH(mem_width)
-                                       | len >> mem_width;
+                                       | len >> reg_width;
                        desc->lli.ctrlb = ctrlb;
 
                        if (!first) {
index 286c3ac6bdcc236d020229ce0397ee9e78e07100..e5e172d21692d60a81fce6a9ed06e5807c57b370 100644 (file)
@@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan)
                 * EIE - Error interrupt enable
                 * EOSIE - End of segments interrupt enable (basic mode)
                 * EOLNIE - End of links interrupt enable
+                * BWC - Bandwidth sharing among channels
                 */
-               DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE
-                               | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
+               DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC
+                               | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE
+                               | FSL_DMA_MR_EOSIE, 32);
                break;
        case FSL_DMA_IP_83XX:
                /* Set the channel to below modes:
index cb4d6ff5159766baf7dce594dca6fb57e3d28dd2..ba9f403c0fbe9127441e7b92bf70c59c71cbde28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Author:
  *   Zhang Wei <wei.zhang@freescale.com>, Jul 2007
 #define FSL_DMA_MR_DAHE                0x00002000
 #define FSL_DMA_MR_SAHE                0x00001000
 
+/*
+ * Bandwidth/pause control determines how many bytes a given
+ * channel is allowed to transfer before the DMA engine pauses
+ * the current channel and switches to the next channel
+ */
+#define FSL_DMA_MR_BWC         0x08000000
+
 /* Special MR definition for MPC8349 */
 #define FSL_DMA_MR_EOTIE       0x00000080
 #define FSL_DMA_MR_PRC_RM      0x00000800
index f629e4961af593f0ab5d3697fce77b306ab1ed9b..e53d438142bb8747cb8f288e64d75b0ba2e18a97 100644 (file)
@@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
        return 0;
 
 err_init:
-       while (i-- >= 0) {
+       while (--i >= 0) {
                struct imxdma_channel *imxdmac = &imxdma->channel[i];
                imx_dma_free(imxdmac->imxdma_channel);
        }
index 0834323a0599595b5a7fa8db1224a85125305031..d0602dd5d1b238eedf2500cd240ef0dc092800a8 100644 (file)
@@ -951,7 +951,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
                struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
                int param;
 
-               bd->buffer_addr = sgl->dma_address;
+               bd->buffer_addr = sg->dma_address;
 
                count = sg->length;
 
@@ -1385,7 +1385,7 @@ static int __init sdma_module_init(void)
 {
        return platform_driver_probe(&sdma_driver, sdma_probe);
 }
-subsys_initcall(sdma_module_init);
+module_init(sdma_module_init);
 
 MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
 MODULE_DESCRIPTION("i.MX SDMA driver");
index 338bc4eed1f3f55b4de66c623a135289862c783f..3109bd94bc4f403c5aba44e8ff7cb092aa23b4cd 100644 (file)
@@ -1075,7 +1075,6 @@ static int mid_setup_dma(struct pci_dev *pdev)
        if (NULL == dma->dma_pool) {
                pr_err("ERR_MDMA:pci_pool_create failed\n");
                err = -ENOMEM;
-               kfree(dma);
                goto err_dma_pool;
        }
 
@@ -1186,7 +1185,6 @@ err_engine:
        free_irq(pdev->irq, dma);
 err_irq:
        pci_pool_destroy(dma->dma_pool);
-       kfree(dma);
 err_dma_pool:
        pr_err("ERR_MDMA:setup_dma failed: %d\n", err);
        return err;
@@ -1413,7 +1411,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = {
        .runtime_idle = dma_runtime_idle,
 };
 
-static struct pci_driver intel_mid_dma_pci = {
+static struct pci_driver intel_mid_dma_pci_driver = {
        .name           =       "Intel MID DMA",
        .id_table       =       intel_mid_dma_ids,
        .probe          =       intel_mid_dma_probe,
@@ -1431,13 +1429,13 @@ static int __init intel_mid_dma_init(void)
 {
        pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n",
                        INTEL_MID_DMA_DRIVER_VERSION);
-       return pci_register_driver(&intel_mid_dma_pci);
+       return pci_register_driver(&intel_mid_dma_pci_driver);
 }
 fs_initcall(intel_mid_dma_init);
 
 static void __exit intel_mid_dma_exit(void)
 {
-       pci_unregister_driver(&intel_mid_dma_pci);
+       pci_unregister_driver(&intel_mid_dma_pci_driver);
 }
 module_exit(intel_mid_dma_exit);
 
index 8997d3fb9051db0020bbeb721cc5a562d780bf47..0ff7270af25b97800d64fcc6f62c350f3115f322 100644 (file)
@@ -1,2 +1,2 @@
 obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
-ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o
+ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o
index 92b679024fedd9e033e9cbae311f7f8d7f221142..c064c89420d06080a737ea48356501aeeae869cd 100644 (file)
@@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
                return;
        }
 
-       channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
-       channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
-       channel_writel(pd_chan, SIZE, desc->regs.size);
-       channel_writel(pd_chan, NEXT, desc->regs.next);
-
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n",
                pd_chan->chan.chan_id, desc->regs.dev_addr);
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n",
@@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n",
                pd_chan->chan.chan_id, desc->regs.next);
 
-       if (list_empty(&desc->tx_list))
+       if (list_empty(&desc->tx_list)) {
+               channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
+               channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
+               channel_writel(pd_chan, SIZE, desc->regs.size);
+               channel_writel(pd_chan, NEXT, desc->regs.next);
                pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT);
-       else
+       } else {
+               channel_writel(pd_chan, NEXT, desc->txd.phys);
                pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG);
+       }
 
        val = dma_readl(pd, CTL2);
        val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id);
index 0d58a4a4487fbbaefc167182a627c6b0b0f222b3..cef584533ee8a9ca5628b874b5d6c644a4ad05f4 100644 (file)
@@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev,
 
        if (!request_mem_region(res.start, resource_size(&res),
                                dev_driver_string(&ofdev->dev))) {
-               dev_err(&ofdev->dev, "failed to request memory region "
-                       "(0x%016llx-0x%016llx)\n",
-                       (u64)res.start, (u64)res.end);
+               dev_err(&ofdev->dev, "failed to request memory region %pR\n",
+                       &res);
                initcode = PPC_ADMA_INIT_MEMREG;
                ret = -EBUSY;
                goto out;
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 8521401bbd751406e6f2752e10868f63c7e3b48a..eca9ba193e94a914aa64740f0b4262b8f7c99b81 100644 (file)
@@ -1572,7 +1572,7 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range,
        debugf1("   HoleOffset=0x%x  HoleValid=0x%x IntlvSel=0x%x\n",
                        hole_off, hole_valid, intlv_sel);
 
-       if (intlv_en ||
+       if (intlv_en &&
            (intlv_sel != ((sys_addr >> 12) & intlv_en)))
                return -EINVAL;
 
index d7ca43a828bd3fe57b3de1341d7e75d1bed84f0a..251440cd50a3b41ea47f4511365909b707ebf0e8 100644 (file)
 #define MC_PROC_NAME_MAX_LEN   7
 
 #if PAGE_SHIFT < 20
-#define PAGES_TO_MiB( pages )  ( ( pages ) >> ( 20 - PAGE_SHIFT ) )
-#define MiB_TO_PAGES(mb)       ((mb) >> (20 - PAGE_SHIFT))
+#define PAGES_TO_MiB(pages)    ((pages) >> (20 - PAGE_SHIFT))
+#define MiB_TO_PAGES(mb)       ((mb) << (20 - PAGE_SHIFT))
 #else                          /* PAGE_SHIFT > 20 */
-#define PAGES_TO_MiB( pages )  ( ( pages ) << ( PAGE_SHIFT - 20 ) )
+#define PAGES_TO_MiB(pages)    ((pages) << (PAGE_SHIFT - 20))
 #define MiB_TO_PAGES(mb)       ((mb) >> (PAGE_SHIFT - 20))
 #endif
 
index ba6586a69ccce3b000fb22ee21512ab4673b44ac..795ea69c4d8f5fb6149c62fba8e085bd83363309 100644 (file)
@@ -586,14 +586,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
                return NULL;
        }
 
-       /* marking MCI offline */
-       mci->op_state = OP_OFFLINE;
-
        del_mc_from_global_list(mci);
        mutex_unlock(&mem_ctls_mutex);
 
-       /* flush workq processes and remove sysfs */
+       /* flush workq processes */
        edac_mc_workq_teardown(mci);
+
+       /* marking MCI offline */
+       mci->op_state = OP_OFFLINE;
+
+       /* remove from sysfs */
        edac_remove_sysfs_mci_device(mci);
 
        edac_printk(KERN_INFO, EDAC_MC,
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 84eb607d6c031b4275e834604d4c0c0729fa8502..e3c8b60bd86be8873e781bef053f466898be16c2 100644 (file)
@@ -242,6 +242,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
 
 static char ohci_driver_name[] = KBUILD_MODNAME;
 
+#define PCI_DEVICE_ID_AGERE_FW643      0x5901
 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW        0x2380
 #define PCI_DEVICE_ID_TI_TSB12LV22     0x8009
 
@@ -253,18 +254,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
 
 /* In case of multiple matches in ohci_quirks[], only the first one is used. */
 static const struct {
-       unsigned short vendor, device, flags;
+       unsigned short vendor, device, revision, flags;
 } ohci_quirks[] = {
-       {PCI_VENDOR_ID_TI,      PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER |
-                                                           QUIRK_RESET_PACKET |
-                                                           QUIRK_NO_1394A},
-       {PCI_VENDOR_ID_TI,      PCI_ANY_ID,     QUIRK_RESET_PACKET},
-       {PCI_VENDOR_ID_AL,      PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI},
-       {PCI_VENDOR_ID_NEC,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_VIA,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_RICOH,   PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_APPLE,   PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
+       {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID,
+               QUIRK_BE_HEADERS},
+
+       {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
+               QUIRK_NO_MSI},
+
+       {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
+               QUIRK_NO_MSI},
+
+       {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
+
+       {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_RESET_PACKET},
+
+       {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
 };
 
 /* This overrides anything that was found in ohci_quirks[]. */
@@ -2927,9 +2944,11 @@ static int __devinit pci_probe(struct pci_dev *dev,
        }
 
        for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++)
-               if (ohci_quirks[i].vendor == dev->vendor &&
-                   (ohci_quirks[i].device == dev->device ||
-                    ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) {
+               if ((ohci_quirks[i].vendor == dev->vendor) &&
+                   (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID ||
+                    ohci_quirks[i].device == dev->device) &&
+                   (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID ||
+                    ohci_quirks[i].revision >= dev->revision)) {
                        ohci->quirks = ohci_quirks[i].flags;
                        break;
                }
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 6985cb1da72cbc232919ab2bb93a52f26304a345..2baa6708e44cd835704ea832c861b7d5fe4b6e33 100644 (file)
@@ -156,12 +156,12 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
        { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
        { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
        { DRM_MODE_CONNECTOR_Component, "Component", 0 },
-       { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
-       { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
-       { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
-       { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
+       { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
+       { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
+       { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
+       { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
        { DRM_MODE_CONNECTOR_TV, "TV", 0 },
-       { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 },
+       { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
 };
 
 static struct drm_prop_enum_list drm_encoder_enum_list[] =
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..16d5155edad14fd63dea3b10243a71c6bd3d0ea1 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;
@@ -626,7 +628,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        if ((seq - vblwait->request.sequence) <= (1 << 23)) {
                e->event.tv_sec = now.tv_sec;
                e->event.tv_usec = now.tv_usec;
-               drm_vblank_put(dev, e->pipe);
+               drm_vblank_put(dev, pipe);
                list_add_tail(&e->base.link, &e->base.file_priv->event_list);
                wake_up_interruptible(&e->base.file_priv->event_wait);
                trace_drm_vblank_event_delivered(current->pid, pipe,
@@ -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, 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..4d7a2e1bdb90e498138eea542e22884c9e36eb0d 100644 (file)
@@ -878,12 +878,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
        u32 tmp;
 
        /* flush hdp cache so updates hit vram */
-       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
+           !(rdev->flags & RADEON_IS_AGP)) {
                void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
                u32 tmp;
 
                /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
                 * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+                * This seems to cause problems on some AGP cards. Just use the old
+                * method for them.
                 */
                WREG32(HDP_DEBUG1, 0);
                tmp = readl((void __iomem *)ptr);
@@ -1195,8 +1198,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 +2723,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) {
@@ -3483,10 +3488,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev)
 void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
 {
        /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
-        * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+        * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL.
+        * This seems to cause problems on some AGP cards. Just use the old
+        * method for them.
         */
        if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
-           rdev->vram_scratch.ptr) {
+           rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) {
                void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
                u32 tmp;
 
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 4bf969c0a32b5ee9cb667a4341759e651f58d569..be0fdd58aa29301fbe15f9186580d724ba769544 100644 (file)
@@ -916,27 +916,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
        int nr = sensor_attr->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct adm1026_data *data = i2c_get_clientdata(client);
-       int val, orig_div, new_div, shift;
+       int val, orig_div, new_div;
 
        val = simple_strtol(buf, NULL, 10);
        new_div = DIV_TO_REG(val);
-       if (new_div == 0) {
-               return -EINVAL;
-       }
+
        mutex_lock(&data->update_lock);
        orig_div = data->fan_div[nr];
        data->fan_div[nr] = DIV_FROM_REG(new_div);
 
        if (nr < 4) { /* 0 <= nr < 4 */
-               shift = 2 * nr;
                adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3,
-                       ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) |
-                       (new_div << shift)));
+                                   (DIV_TO_REG(data->fan_div[0]) << 0) |
+                                   (DIV_TO_REG(data->fan_div[1]) << 2) |
+                                   (DIV_TO_REG(data->fan_div[2]) << 4) |
+                                   (DIV_TO_REG(data->fan_div[3]) << 6));
        } else { /* 3 < nr < 8 */
-               shift = 2 * (nr - 4);
                adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7,
-                       ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) |
-                       (new_div << shift)));
+                                   (DIV_TO_REG(data->fan_div[4]) << 0) |
+                                   (DIV_TO_REG(data->fan_div[5]) << 2) |
+                                   (DIV_TO_REG(data->fan_div[6]) << 4) |
+                                   (DIV_TO_REG(data->fan_div[7]) << 6));
        }
 
        if (data->fan_div[nr] != orig_div) {
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 14a5d981be7d07030a264352dbc8d8af1e158c2d..a428a92641954a640dd783f051fc9c5565c13d9b 100644 (file)
@@ -187,6 +187,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
 #define IT87_REG_FAN_MAIN_CTRL 0x13
 #define IT87_REG_FAN_CTL       0x14
 #define IT87_REG_PWM(nr)       (0x15 + (nr))
+#define IT87_REG_PWM_DUTY(nr)  (0x63 + (nr) * 8)
 
 #define IT87_REG_VIN(nr)       (0x20 + (nr))
 #define IT87_REG_TEMP(nr)      (0x29 + (nr))
@@ -251,12 +252,16 @@ struct it87_data {
        u8 fan_main_ctrl;       /* Register value */
        u8 fan_ctl;             /* Register value */
 
-       /* The following 3 arrays correspond to the same registers. The
-        * meaning of bits 6-0 depends on the value of bit 7, and we want
-        * to preserve settings on mode changes, so we have to track all
-        * values separately. */
+       /* The following 3 arrays correspond to the same registers up to
+        * the IT8720F. The meaning of bits 6-0 depends on the value of bit
+        * 7, and we want to preserve settings on mode changes, so we have
+        * to track all values separately.
+        * Starting with the IT8721F, the manual PWM duty cycles are stored
+        * in separate registers (8-bit values), so the separate tracking
+        * is no longer needed, but it is still done to keep the driver
+        * simple. */
        u8 pwm_ctrl[3];         /* Register value */
-       u8 pwm_duty[3];         /* Manual PWM value set by user (bit 6-0) */
+       u8 pwm_duty[3];         /* Manual PWM value set by user */
        u8 pwm_temp_map[3];     /* PWM to temp. chan. mapping (bits 1-0) */
 
        /* Automatic fan speed control registers */
@@ -832,7 +837,9 @@ static ssize_t set_pwm_enable(struct device *dev,
                                 data->fan_main_ctrl);
        } else {
                if (val == 1)                           /* Manual mode */
-                       data->pwm_ctrl[nr] = data->pwm_duty[nr];
+                       data->pwm_ctrl[nr] = data->type == it8721 ?
+                                            data->pwm_temp_map[nr] :
+                                            data->pwm_duty[nr];
                else                                    /* Automatic mode */
                        data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
                it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
@@ -858,12 +865,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
-       data->pwm_duty[nr] = pwm_to_reg(data, val);
-       /* If we are in manual mode, write the duty cycle immediately;
-        * otherwise, just store it for later use. */
-       if (!(data->pwm_ctrl[nr] & 0x80)) {
-               data->pwm_ctrl[nr] = data->pwm_duty[nr];
-               it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
+       if (data->type == it8721) {
+               /* If we are in automatic mode, the PWM duty cycle register
+                * is read-only so we can't write the value */
+               if (data->pwm_ctrl[nr] & 0x80) {
+                       mutex_unlock(&data->update_lock);
+                       return -EBUSY;
+               }
+               data->pwm_duty[nr] = pwm_to_reg(data, val);
+               it87_write_value(data, IT87_REG_PWM_DUTY(nr),
+                                data->pwm_duty[nr]);
+       } else {
+               data->pwm_duty[nr] = pwm_to_reg(data, val);
+               /* If we are in manual mode, write the duty cycle immediately;
+                * otherwise, just store it for later use. */
+               if (!(data->pwm_ctrl[nr] & 0x80)) {
+                       data->pwm_ctrl[nr] = data->pwm_duty[nr];
+                       it87_write_value(data, IT87_REG_PWM(nr),
+                                        data->pwm_ctrl[nr]);
+               }
        }
        mutex_unlock(&data->update_lock);
        return count;
@@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
         *   channels to use when later setting to automatic mode later.
         *   Use a 1:1 mapping by default (we are clueless.)
         * In both cases, the value can (and should) be changed by the user
-        * prior to switching to a different mode. */
+        * prior to switching to a different mode.
+        * Note that this is no longer needed for the IT8721F and later, as
+        * these have separate registers for the temperature mapping and the
+        * manual duty cycle. */
        for (i = 0; i < 3; i++) {
                data->pwm_temp_map[i] = i;
                data->pwm_duty[i] = 0x7f;       /* Full speed */
@@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev)
 static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
 {
        data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
-       if (data->pwm_ctrl[nr] & 0x80)  /* Automatic mode */
+       if (data->type == it8721) {
                data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
-       else                            /* Manual mode */
-               data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+               data->pwm_duty[nr] = it87_read_value(data,
+                                                    IT87_REG_PWM_DUTY(nr));
+       } else {
+               if (data->pwm_ctrl[nr] & 0x80)  /* Automatic mode */
+                       data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+               else                            /* Manual mode */
+                       data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+       }
 
        if (has_old_autopwm(data)) {
                int i;
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 00d975eb5b83dcc86ddd8d5f5b6846c9d370f6e6..c7e6d8e81656391e7f7919d5e4c92d08a69b1700 100644 (file)
@@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm,      (1 << 2),       LTC4215_STATUS);
 
 /* Power (virtual) */
 LTC4215_POWER(power1_input);
-LTC4215_ALARM(power1_alarm,    (1 << 3),       LTC4215_STATUS);
 
 /* Input Voltage */
 LTC4215_VOLTAGE(in1_input,                     LTC4215_ADIN);
@@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm,        (1 << 1),       LTC4215_STATUS);
 
 /* Output Voltage */
 LTC4215_VOLTAGE(in2_input,                     LTC4215_SOURCE);
+LTC4215_ALARM(in2_min_alarm,   (1 << 3),       LTC4215_STATUS);
 
 /* Finally, construct an array of pointers to members of the above objects,
  * as required for sysfs_create_group()
@@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = {
        &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
 
        &sensor_dev_attr_power1_input.dev_attr.attr,
-       &sensor_dev_attr_power1_alarm.dev_attr.attr,
 
        &sensor_dev_attr_in1_input.dev_attr.attr,
        &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
        &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
 
        &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
 
        NULL,
 };
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 80f70d3a744dc65024c868843a66cd336fd53ce5..c71492782bbd4dda6e1f4a585adbba419ce4694d 100644 (file)
@@ -999,7 +999,7 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev,
 
        /* Initialize struct members */
        snprintf(mrst->adap.name, sizeof(mrst->adap.name),
-               "MRST/Medfield I2C at %lx", start);
+               "Intel MID I2C at %lx", start);
        mrst->adap.owner = THIS_MODULE;
        mrst->adap.algo = &intel_mid_i2c_algorithm;
        mrst->adap.dev.parent = &dev->dev;
index 41665d2f9f93c1fa585533184468da72039fe7cf..c131d58bcb50d818e05ee0464581bceedfdbf20f 100644 (file)
@@ -273,8 +273,6 @@ static int intel_idle_probe(void)
 
        pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
 
-       if (boot_cpu_has(X86_FEATURE_ARAT))     /* Always Reliable APIC Timer */
-               lapic_timer_reliable_states = 0xFFFFFFFF;
 
        if (boot_cpu_data.x86 != 6)     /* family 6 */
                return -ENODEV;
@@ -286,8 +284,6 @@ static int intel_idle_probe(void)
        case 0x1F:      /* Core i7 and i5 Processor - Nehalem */
        case 0x2E:      /* Nehalem-EX Xeon */
        case 0x2F:      /* Westmere-EX Xeon */
-               lapic_timer_reliable_states = (1 << 1);  /* C1 */
-
        case 0x25:      /* Westmere */
        case 0x2C:      /* Westmere */
                cpuidle_state_table = nehalem_cstates;
@@ -295,7 +291,6 @@ static int intel_idle_probe(void)
 
        case 0x1C:      /* 28 - Atom Processor */
        case 0x26:      /* 38 - Lincroft Atom Processor */
-               lapic_timer_reliable_states = (1 << 1); /* C1 */
                cpuidle_state_table = atom_cstates;
                break;
 
@@ -303,10 +298,6 @@ static int intel_idle_probe(void)
        case 0x2D:      /* SNB Xeon */
                cpuidle_state_table = snb_cstates;
                break;
-#ifdef FUTURE_USE
-       case 0x17:      /* 23 - Core 2 Duo */
-               lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
-#endif
 
        default:
                pr_debug(PREFIX "does not run on family %d model %d\n",
@@ -314,6 +305,9 @@ static int intel_idle_probe(void)
                return -ENODEV;
        }
 
+       if (boot_cpu_has(X86_FEATURE_ARAT))     /* Always Reliable APIC Timer */
+               lapic_timer_reliable_states = 0xFFFFFFFF;
+
        pr_debug(PREFIX "v" INTEL_IDLE_VERSION
                " model 0x%X\n", boot_cpu_data.x86_model);
 
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 b342248aec059060e19f64ffd69ec28af256682a..c42699285f8eb0d67745c359afadc6e125e7815d 100644 (file)
@@ -893,68 +893,81 @@ out:
        return ret ? ret : in_len;
 }
 
+static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
+{
+       struct ib_uverbs_wc tmp;
+
+       tmp.wr_id               = wc->wr_id;
+       tmp.status              = wc->status;
+       tmp.opcode              = wc->opcode;
+       tmp.vendor_err          = wc->vendor_err;
+       tmp.byte_len            = wc->byte_len;
+       tmp.ex.imm_data         = (__u32 __force) wc->ex.imm_data;
+       tmp.qp_num              = wc->qp->qp_num;
+       tmp.src_qp              = wc->src_qp;
+       tmp.wc_flags            = wc->wc_flags;
+       tmp.pkey_index          = wc->pkey_index;
+       tmp.slid                = wc->slid;
+       tmp.sl                  = wc->sl;
+       tmp.dlid_path_bits      = wc->dlid_path_bits;
+       tmp.port_num            = wc->port_num;
+       tmp.reserved            = 0;
+
+       if (copy_to_user(dest, &tmp, sizeof tmp))
+               return -EFAULT;
+
+       return 0;
+}
+
 ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
                          const char __user *buf, int in_len,
                          int out_len)
 {
        struct ib_uverbs_poll_cq       cmd;
-       struct ib_uverbs_poll_cq_resp *resp;
+       struct ib_uverbs_poll_cq_resp  resp;
+       u8 __user                     *header_ptr;
+       u8 __user                     *data_ptr;
        struct ib_cq                  *cq;
-       struct ib_wc                  *wc;
-       int                            ret = 0;
-       int                            i;
-       int                            rsize;
+       struct ib_wc                   wc;
+       int                            ret;
 
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
 
-       wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
-       if (!wc)
-               return -ENOMEM;
-
-       rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
-       resp = kmalloc(rsize, GFP_KERNEL);
-       if (!resp) {
-               ret = -ENOMEM;
-               goto out_wc;
-       }
-
        cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
-       if (!cq) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (!cq)
+               return -EINVAL;
 
-       resp->count = ib_poll_cq(cq, cmd.ne, wc);
+       /* we copy a struct ib_uverbs_poll_cq_resp to user space */
+       header_ptr = (void __user *)(unsigned long) cmd.response;
+       data_ptr = header_ptr + sizeof resp;
 
-       put_cq_read(cq);
+       memset(&resp, 0, sizeof resp);
+       while (resp.count < cmd.ne) {
+               ret = ib_poll_cq(cq, 1, &wc);
+               if (ret < 0)
+                       goto out_put;
+               if (!ret)
+                       break;
+
+               ret = copy_wc_to_user(data_ptr, &wc);
+               if (ret)
+                       goto out_put;
 
-       for (i = 0; i < resp->count; i++) {
-               resp->wc[i].wr_id          = wc[i].wr_id;
-               resp->wc[i].status         = wc[i].status;
-               resp->wc[i].opcode         = wc[i].opcode;
-               resp->wc[i].vendor_err     = wc[i].vendor_err;
-               resp->wc[i].byte_len       = wc[i].byte_len;
-               resp->wc[i].ex.imm_data    = (__u32 __force) wc[i].ex.imm_data;
-               resp->wc[i].qp_num         = wc[i].qp->qp_num;
-               resp->wc[i].src_qp         = wc[i].src_qp;
-               resp->wc[i].wc_flags       = wc[i].wc_flags;
-               resp->wc[i].pkey_index     = wc[i].pkey_index;
-               resp->wc[i].slid           = wc[i].slid;
-               resp->wc[i].sl             = wc[i].sl;
-               resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
-               resp->wc[i].port_num       = wc[i].port_num;
+               data_ptr += sizeof(struct ib_uverbs_wc);
+               ++resp.count;
        }
 
-       if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
+       if (copy_to_user(header_ptr, &resp, sizeof resp)) {
                ret = -EFAULT;
+               goto out_put;
+       }
 
-out:
-       kfree(resp);
+       ret = in_len;
 
-out_wc:
-       kfree(wc);
-       return ret ? ret : in_len;
+out_put:
+       put_cq_read(cq);
+       return ret;
 }
 
 ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
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 3bacccab1b8ccc250aefc032bbc6b430e85ee081..982fc347ebe479ddee1cf907937033fb616d661b 100644 (file)
@@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err)
        bio_put(bio);
 }
 
-static void submit_flushes(mddev_t *mddev)
+static void md_submit_flush_data(struct work_struct *ws);
+
+static void submit_flushes(struct work_struct *ws)
 {
+       mddev_t *mddev = container_of(ws, mddev_t, flush_work);
        mdk_rdev_t *rdev;
 
+       INIT_WORK(&mddev->flush_work, md_submit_flush_data);
+       atomic_set(&mddev->flush_pending, 1);
        rcu_read_lock();
        list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
                if (rdev->raid_disk >= 0 &&
@@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev)
                        rdev_dec_pending(rdev, mddev);
                }
        rcu_read_unlock();
+       if (atomic_dec_and_test(&mddev->flush_pending))
+               queue_work(md_wq, &mddev->flush_work);
 }
 
 static void md_submit_flush_data(struct work_struct *ws)
@@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws)
        mddev_t *mddev = container_of(ws, mddev_t, flush_work);
        struct bio *bio = mddev->flush_bio;
 
-       atomic_set(&mddev->flush_pending, 1);
-
        if (bio->bi_size == 0)
                /* an empty barrier - all done */
                bio_endio(bio, 0);
@@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws)
                if (mddev->pers->make_request(mddev, bio))
                        generic_make_request(bio);
        }
-       if (atomic_dec_and_test(&mddev->flush_pending)) {
-               mddev->flush_bio = NULL;
-               wake_up(&mddev->sb_wait);
-       }
+
+       mddev->flush_bio = NULL;
+       wake_up(&mddev->sb_wait);
 }
 
 void md_flush_request(mddev_t *mddev, struct bio *bio)
@@ -429,13 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio)
        mddev->flush_bio = bio;
        spin_unlock_irq(&mddev->write_lock);
 
-       atomic_set(&mddev->flush_pending, 1);
-       INIT_WORK(&mddev->flush_work, md_submit_flush_data);
-
-       submit_flushes(mddev);
-
-       if (atomic_dec_and_test(&mddev->flush_pending))
-               queue_work(md_wq, &mddev->flush_work);
+       INIT_WORK(&mddev->flush_work, submit_flushes);
+       queue_work(md_wq, &mddev->flush_work);
 }
 EXPORT_SYMBOL(md_flush_request);
 
@@ -1337,7 +1336,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 +1703,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[] = {
@@ -4330,6 +4329,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) {
@@ -5150,7 +5151,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
                                PTR_ERR(rdev));
                        return PTR_ERR(rdev);
                }
-               /* set save_raid_disk if appropriate */
+               /* set saved_raid_disk if appropriate */
                if (!mddev->persistent) {
                        if (info->state & (1<<MD_DISK_SYNC)  &&
                            info->raid_disk < mddev->raid_disks)
@@ -5160,7 +5161,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
                } else
                        super_types[mddev->major_version].
                                validate_super(mddev, rdev);
-               rdev->saved_raid_disk = rdev->raid_disk;
+               if (test_bit(In_sync, &rdev->flags))
+                       rdev->saved_raid_disk = rdev->raid_disk;
+               else
+                       rdev->saved_raid_disk = -1;
 
                clear_bit(In_sync, &rdev->flags); /* just to be sure */
                if (info->state & (1<<MD_DISK_WRITEMOSTLY))
@@ -6032,9 +6036,8 @@ static int md_thread(void * arg)
                         || kthread_should_stop(),
                         thread->timeout);
 
-               clear_bit(THREAD_WAKEUP, &thread->flags);
-
-               thread->run(thread->mddev);
+               if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags))
+                       thread->run(thread->mddev);
        }
 
        return 0;
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 c67aa54694ae72605b2165949fe1033dc2d542b9..0641674827f06786dee5549ada83b23820928748 100644 (file)
@@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev)
        return 0;
 
 out_free_conf:
+       md_unregister_thread(mddev->thread);
        if (conf->r10bio_pool)
                mempool_destroy(conf->r10bio_pool);
        safe_put_page(conf->tmppage);
        kfree(conf->mirrors);
        kfree(conf);
        mddev->private = NULL;
-       md_unregister_thread(mddev->thread);
 out:
        return -EIO;
 }
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 dd90880048cf3fe2f8d209ad654159565a5987e4..d8ae634d347ebc4262704188adb1dea943c909e6 100644 (file)
@@ -51,7 +51,7 @@ struct pxa2xx_flash_info {
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 
-static int __init pxa2xx_flash_probe(struct platform_device *pdev)
+static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *flash = pdev->dev.platform_data;
        struct pxa2xx_flash_info *info;
index cd41c58b5bbd50f8ed905a1a6da71dedc5cfca7e..15682ec8530ed008f8f3f8ddbd16e577306a6407 100644 (file)
@@ -7,7 +7,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define CONFIG_MTD_NAND_OMAP_HWECC
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
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 c6e86315b3f8df37aa2ac1a767ac46fc1b5eba60..2e2b76258ab42cbc6b0dc73f70bd9547a5846857 100644 (file)
@@ -381,11 +381,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
        __b44_set_flow_ctrl(bp, pause_enab);
 }
 
-#ifdef SSB_DRIVER_MIPS
-extern char *nvram_get(char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
 static void b44_wap54g10_workaround(struct b44 *bp)
 {
-       const char *str;
+       char buf[20];
        u32 val;
        int err;
 
@@ -394,10 +394,9 @@ static void b44_wap54g10_workaround(struct b44 *bp)
         * see https://dev.openwrt.org/ticket/146
         * check and reset bit "isolate"
         */
-       str = nvram_get("boardnum");
-       if (!str)
+       if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
                return;
-       if (simple_strtoul(str, NULL, 0) == 2) {
+       if (simple_strtoul(buf, NULL, 0) == 2) {
                err = __b44_readphy(bp, 0, MII_BMCR, &val);
                if (err)
                        goto error;
index 36eca1ce75d4e29a4c41bbf285931ce003a6a92a..e4465d222a7d019654c27c5f4d3db89067f89cf8 100644 (file)
@@ -1235,7 +1235,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 
                i = 0;
                netdev_for_each_mc_addr(ha, netdev)
-                       memcpy(req->mac[i].byte, ha->addr, ETH_ALEN);
+                       memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN);
        } else {
                req->promiscuous = 1;
        }
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 863e73a85fbe0ef4cd48ebac5cd5e95846397ebc..d255428122fc0b87d3e4ff2925410b5b2d5f6a47 100644 (file)
@@ -20,8 +20,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.60.00-4"
-#define DRV_MODULE_RELDATE      "2010/11/01"
+#define DRV_MODULE_VERSION      "1.60.01-0"
+#define DRV_MODULE_RELDATE      "2010/11/12"
 #define BNX2X_BC_VER            0x040200
 
 #define BNX2X_MULTI_QUEUE
index 94d5f59d5a6f0a1de6dd8cc5ad44fc2083649b98..0af361e4e3d16ab83d8c3067396f63c5d46d1cb1 100644 (file)
@@ -1782,15 +1782,15 @@ exit_lbl:
 }
 #endif
 
-static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb,
-                                    struct eth_tx_parse_bd_e2 *pbd,
-                                    u32 xmit_type)
+static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
+                                       u32 xmit_type)
 {
-       pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) <<
-               ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT;
+       *parsing_data |= (skb_shinfo(skb)->gso_size <<
+                             ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
+                             ETH_TX_PARSE_BD_E2_LSO_MSS;
        if ((xmit_type & XMIT_GSO_V6) &&
            (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6))
-               pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
+               *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
 }
 
 /**
@@ -1835,15 +1835,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
  * @return header len
  */
 static inline  u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
-       struct eth_tx_parse_bd_e2 *pbd,
-       u32 xmit_type)
+       u32 *parsing_data, u32 xmit_type)
 {
-       pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) <<
-               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT;
+       *parsing_data |= ((tcp_hdrlen(skb)/4) <<
+               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) &
+               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW;
 
-       pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) -
-                                         skb->data) / 2) <<
-               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT;
+       *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) <<
+               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) &
+               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W;
 
        return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data;
 }
@@ -1912,6 +1912,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
        struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
        struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
+       u32 pbd_e2_parsing_data = 0;
        u16 pkt_prod, bd_prod;
        int nbd, fp_index;
        dma_addr_t mapping;
@@ -2033,8 +2034,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
                /* Set PBD in checksum offload case */
                if (xmit_type & XMIT_CSUM)
-                       hlen = bnx2x_set_pbd_csum_e2(bp,
-                                                    skb, pbd_e2, xmit_type);
+                       hlen = bnx2x_set_pbd_csum_e2(bp, skb,
+                                                    &pbd_e2_parsing_data,
+                                                    xmit_type);
        } else {
                pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x;
                memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
@@ -2076,10 +2078,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd,
                                                 hlen, bd_prod, ++nbd);
                if (CHIP_IS_E2(bp))
-                       bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type);
+                       bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
+                                            xmit_type);
                else
                        bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
        }
+
+       /* Set the PBD's parsing_data field if not zero
+        * (for the chips newer than 57711).
+        */
+       if (pbd_e2_parsing_data)
+               pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data);
+
        tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
 
        /* Handle fragmented skb */
index a306b0e46b613417c630e79398c5f8250204195d..66df29fcf7516e45b7794fee314d0122fca6d42b 100644 (file)
@@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
 /****************************************************************************
 * SRC initializations
 ****************************************************************************/
-
+#ifdef BCM_CNIC
 /* called during init func stage */
 static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
                              dma_addr_t t2_mapping, int src_cid_count)
@@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
                    U64_HI((u64)t2_mapping +
                           (src_cid_count-1) * sizeof(struct src_ent)));
 }
-
+#endif
 #endif /* BNX2X_INIT_OPS_H */
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..d0ea760ce419f0ae8040bf880cd80013c651a93a 100644 (file)
@@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link
 /*----------------------------- Global variables ----------------------------*/
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-cpumask_var_t netpoll_block_tx;
+atomic_t netpoll_block_tx = ATOMIC_INIT(0);
 #endif
 
 static const char * const version =
@@ -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();
@@ -1574,7 +1576,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        /* If this is the first slave, then we need to set the master's hardware
         * address to be the same as the slave's. */
-       if (bond->slave_cnt == 0)
+       if (is_zero_ether_addr(bond->dev->dev_addr))
                memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
                       slave_dev->addr_len);
 
@@ -5297,13 +5299,6 @@ static int __init bonding_init(void)
        if (res)
                goto out;
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) {
-               res = -ENOMEM;
-               goto out;
-       }
-#endif
-
        res = register_pernet_subsys(&bond_net_ops);
        if (res)
                goto out;
@@ -5332,9 +5327,6 @@ err:
        rtnl_link_unregister(&bond_link_ops);
 err_link:
        unregister_pernet_subsys(&bond_net_ops);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       free_cpumask_var(netpoll_block_tx);
-#endif
        goto out;
 
 }
@@ -5351,7 +5343,10 @@ static void __exit bonding_exit(void)
        unregister_pernet_subsys(&bond_net_ops);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-       free_cpumask_var(netpoll_block_tx);
+       /*
+        * Make sure we don't have an imbalance on our netpoll blocking
+        */
+       WARN_ON(atomic_read(&netpoll_block_tx));
 #endif
 }
 
index 4eedb12df6caf2e4676cbe11e2134e97ec01def1..c2f081352a037894d6e8238ccb70c39e796c4a69 100644 (file)
 
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-extern cpumask_var_t netpoll_block_tx;
+extern atomic_t netpoll_block_tx;
 
 static inline void block_netpoll_tx(void)
 {
-       preempt_disable();
-       BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(),
-                                       netpoll_block_tx));
+       atomic_inc(&netpoll_block_tx);
 }
 
 static inline void unblock_netpoll_tx(void)
 {
-       BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(),
-                                          netpoll_block_tx));
-       preempt_enable();
+       atomic_dec(&netpoll_block_tx);
 }
 
 static inline int is_netpoll_tx_blocked(struct net_device *dev)
 {
        if (unlikely(dev->priv_flags & IFF_IN_NETPOLL))
-               return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx);
+               return atomic_read(&netpoll_block_tx);
        return 0;
 }
 #else
index 1cd90da86f130ea588070634db35959a47ca7b87..32b1c6fb2de1a74e5b97254cdf075ca933464734 100644 (file)
@@ -5,7 +5,7 @@
  * License terms: GNU General Public License (GPL) version 2
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
 
 #include <linux/version.h>
 #include <linux/init.h>
index 19f9c065666745633752c3e59b312d2a4e9812c0..80511167f35bd4bcfb53cf424eb58ff4174a558b 100644 (file)
@@ -6,7 +6,7 @@
  * License terms: GNU General Public License (GPL) version 2
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
 
 #include <linux/spinlock.h>
 #include <linux/sched.h>
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 bb813d94aea8ef5ae11db63ce6ac795fd0a62c39..e97521c801ea6e4a90714bd2038d4c0610b8806a 100644 (file)
@@ -2408,7 +2408,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
                if (index < NEXACT_MAC)
                        ret++;
                else if (hash)
-                       *hash |= (1 << hash_mac_addr(addr[i]));
+                       *hash |= (1ULL << hash_mac_addr(addr[i]));
        }
        return ret;
 }
index c3449bbc585a682b57a39b306f251f9691e27e0b..6bf464afa90ed1a60cf06bb91f31964cf82a7e5d 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,
@@ -2252,6 +2269,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
 {
        struct sge *s = &adapter->sge;
        int q10g, n10g, qidx, pidx, qs;
+       size_t iqe_size;
 
        /*
         * We should not be called till we know how many Queue Sets we can
@@ -2295,6 +2313,13 @@ static void __devinit cfg_queues(struct adapter *adapter)
        }
        s->ethqsets = qidx;
 
+       /*
+        * The Ingress Queue Entry Size for our various Response Queues needs
+        * to be big enough to accommodate the largest message we can receive
+        * from the chip/firmware; which is 64 bytes ...
+        */
+       iqe_size = 64;
+
        /*
         * Set up default Queue Set parameters ...  Start off with the
         * shortest interrupt holdoff timer.
@@ -2303,7 +2328,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
                struct sge_eth_rxq *rxq = &s->ethrxq[qs];
                struct sge_eth_txq *txq = &s->ethtxq[qs];
 
-               init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES);
+               init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size);
                rxq->fl.size = 72;
                txq->q.size = 1024;
        }
@@ -2312,8 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
         * The firmware event queue is used for link state changes and
         * notifications of TX DMA completions.
         */
-       init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512,
-                 L1_CACHE_BYTES);
+       init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size);
 
        /*
         * The forwarded interrupt queue is used when we're in MSI interrupt
@@ -2329,7 +2353,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
         * any time ...
         */
        init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1,
-                 L1_CACHE_BYTES);
+                 iqe_size);
 }
 
 /*
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 75b099ce49c9b47e361adc66da99d148b58640f3..1f37ee6b2a2626282fd5a772cc21f821321b9379 100644 (file)
@@ -261,6 +261,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev,
 
 }
 
+static int ehea_set_flags(struct net_device *dev, u32 data)
+{
+       return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
+                                       | ETH_FLAG_TXVLAN
+                                       | ETH_FLAG_RXVLAN);
+}
+
 const struct ethtool_ops ehea_ethtool_ops = {
        .get_settings = ehea_get_settings,
        .get_drvinfo = ehea_get_drvinfo,
@@ -273,6 +280,8 @@ const struct ethtool_ops ehea_ethtool_ops = {
        .get_ethtool_stats = ehea_get_ethtool_stats,
        .get_rx_csum = ehea_get_rx_csum,
        .set_settings = ehea_set_settings,
+       .get_flags = ethtool_op_get_flags,
+       .set_flags = ehea_set_flags,
        .nway_reset = ehea_nway_reset,          /* Restart autonegotiation */
 };
 
index 182b2a7be8dcd02673bd9512d2760cb61b86b884..b95f087cd5a9c4a51525718e90ba65b56cf81b99 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,
@@ -675,7 +683,7 @@ static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe,
        int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) &&
                              pr->port->vgrp);
 
-       if (use_lro) {
+       if (skb->dev->features & NETIF_F_LRO) {
                if (vlan_extracted)
                        lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb,
                                                     pr->port->vgrp,
@@ -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);
@@ -777,7 +787,7 @@ static int ehea_proc_rwqes(struct net_device *dev,
                }
                cqe = ehea_poll_rq1(qp, &wqe_index);
        }
-       if (use_lro)
+       if (dev->features & NETIF_F_LRO)
                lro_flush_all(&pr->lro_mgr);
 
        pr->rx_packets += processed;
@@ -3268,6 +3278,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
                      | NETIF_F_LLTX;
        dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
 
+       if (use_lro)
+               dev->features |= NETIF_F_LRO;
+
        INIT_WORK(&port->reset_task, ehea_reset_port);
 
        ret = register_netdev(dev);
index a466ef91dd4351d58f37e4ed5b443395ce4725e6..aa28b270c045e1a32562be18f68a1ec0449f276f 100644 (file)
@@ -1962,7 +1962,8 @@ static void enic_poll_controller(struct net_device *netdev)
        case VNIC_DEV_INTR_MODE_MSIX:
                for (i = 0; i < enic->rq_count; i++) {
                        intr = enic_msix_rq_intr(enic, i);
-                       enic_isr_msix_rq(enic->msix_entry[intr].vector, enic);
+                       enic_isr_msix_rq(enic->msix_entry[intr].vector,
+                               &enic->napi[i]);
                }
                intr = enic_msix_wq_intr(enic, i);
                enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
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 ab9f675c5b8b8b86473d07b60b3ad933523b3ab5..fe337bd121aa74d3eb60cf866e31b8f76fa84573 100644 (file)
@@ -104,6 +104,8 @@ static void ri_tasklet(unsigned long dev)
                        rcu_read_unlock();
                        dev_kfree_skb(skb);
                        stats->tx_dropped++;
+                       if (skb_queue_len(&dp->tq) != 0)
+                               goto resched;
                        break;
                }
                rcu_read_unlock();
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 fbad4d819608f234d0eff25175bccf9a8545c20b..eee0b298bd3616558ca8d9f5cf44a02fe95c68e7 100644 (file)
@@ -4771,6 +4771,9 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
                adapter->rx_ring[i] = NULL;
        }
 
+       adapter->num_tx_queues = 0;
+       adapter->num_rx_queues = 0;
+
        ixgbe_free_q_vectors(adapter);
        ixgbe_reset_interrupt_capability(adapter);
 }
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 cb3d13e4e074097a4b89b9f0315f3d64b6ad68ff..35fda5ac8120c056eb94d0f14bea376494d2d59c 100644 (file)
@@ -64,7 +64,7 @@ config BCM63XX_PHY
 config ICPLUS_PHY
        tristate "Drivers for ICPlus PHYs"
        ---help---
-         Currently supports the IP175C PHY.
+         Currently supports the IP175C and IP1001 PHYs.
 
 config REALTEK_PHY
        tristate "Drivers for Realtek PHYs"
index c1d2d251fe8bfcef7114fd57b1018c70697006f5..9a09e24c30bc2e222974b481f76d219ed6a22cd6 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-MODULE_DESCRIPTION("ICPlus IP175C PHY driver");
+MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers");
 MODULE_AUTHOR("Michael Barkowski");
 MODULE_LICENSE("GPL");
 
@@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static int ip1001_config_init(struct phy_device *phydev)
+{
+       int err, value;
+
+       /* Software Reset PHY */
+       value = phy_read(phydev, MII_BMCR);
+       value |= BMCR_RESET;
+       err = phy_write(phydev, MII_BMCR, value);
+       if (err < 0)
+               return err;
+
+       do {
+               value = phy_read(phydev, MII_BMCR);
+       } while (value & BMCR_RESET);
+
+       /* Additional delay (2ns) used to adjust RX clock phase
+        * at GMII/ RGMII interface */
+       value = phy_read(phydev, 16);
+       value |= 0x3;
+
+       err = phy_write(phydev, 16, value);
+       if (err < 0)
+               return err;
+
+       return err;
+}
+
 static int ip175c_read_status(struct phy_device *phydev)
 {
        if (phydev->addr == 4) /* WAN port */
@@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = {
        .driver         = { .owner = THIS_MODULE,},
 };
 
-static int __init ip175c_init(void)
+static struct phy_driver ip1001_driver = {
+       .phy_id         = 0x02430d90,
+       .name           = "ICPlus IP1001",
+       .phy_id_mask    = 0x0ffffff0,
+       .features       = PHY_GBIT_FEATURES | SUPPORTED_Pause |
+                         SUPPORTED_Asym_Pause,
+       .config_init    = &ip1001_config_init,
+       .config_aneg    = &genphy_config_aneg,
+       .read_status    = &genphy_read_status,
+       .suspend        = genphy_suspend,
+       .resume         = genphy_resume,
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static int __init icplus_init(void)
 {
+       int ret = 0;
+
+       ret = phy_driver_register(&ip1001_driver);
+       if (ret < 0)
+               return -ENODEV;
+
        return phy_driver_register(&ip175c_driver);
 }
 
-static void __exit ip175c_exit(void)
+static void __exit icplus_exit(void)
 {
+       phy_driver_unregister(&ip1001_driver);
        phy_driver_unregister(&ip175c_driver);
 }
 
-module_init(ip175c_init);
-module_exit(ip175c_exit);
+module_init(icplus_init);
+module_exit(icplus_exit);
 
 static struct mdio_device_id __maybe_unused icplus_tbl[] = {
        { 0x02430d80, 0x0ffffff0 },
+       { 0x02430d90, 0x0ffffff0 },
        { }
 };
 
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 d72fb0519a2aa674a8757f5146b0df19655d9749..78c0e3c9b2b5fcb8d42fb910ab2416e4db787dc7 100644 (file)
@@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
 
 abort:
        kfree_skb(skb);
-       return 0;
+       return 1;
 }
 
 /************************************************************************
index 22821398fc63765054eff056ab2529beedfb30fc..9787dff90d3fa18a3e70cbdac43fa73062202b33 100644 (file)
@@ -2083,6 +2083,7 @@ struct ql_adapter {
        u32 mailbox_in;
        u32 mailbox_out;
        struct mbox_params idc_mbc;
+       struct mutex    mpi_mutex;
 
        int tx_ring_size;
        int rx_ring_size;
index c30e0fe55a314858828c2caa4d464b0c2301fe81..2555b1d34f346d691f904bb3f8593a3933f2b6fc 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;
@@ -4629,6 +4629,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
        INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
        INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log);
        init_completion(&qdev->ide_completion);
+       mutex_init(&qdev->mpi_mutex);
 
        if (!cards_found) {
                dev_info(&pdev->dev, "%s\n", DRV_STRING);
index 0e7c7c7ee1647006baf561ffd90308290fbd2399..a2e919bcb3c6b616250eeafb4e76ae7a5921f50e 100644 (file)
@@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
        int status;
        unsigned long count;
 
+       mutex_lock(&qdev->mpi_mutex);
 
        /* Begin polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -603,6 +604,7 @@ done:
 end:
        /* End polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+       mutex_unlock(&qdev->mpi_mutex);
        return status;
 }
 
@@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev)
 static int ql_set_port_cfg(struct ql_adapter *qdev)
 {
        int status;
-       rtnl_lock();
        status = ql_mb_set_port_cfg(qdev);
-       rtnl_unlock();
        if (status)
                return status;
        status = ql_idc_wait(qdev);
@@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
            container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
        int status;
 
-       rtnl_lock();
        status = ql_mb_get_port_cfg(qdev);
-       rtnl_unlock();
        if (status) {
                netif_err(qdev, drv, qdev->ndev,
                          "Bug: Failed to get port config data.\n");
@@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work)
        u32 aen;
        int timeout;
 
-       rtnl_lock();
        aen = mbcp->mbox_out[1] >> 16;
        timeout = (mbcp->mbox_out[1] >> 8) & 0xf;
 
@@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work)
                }
                break;
        }
-       rtnl_unlock();
 }
 
 void ql_mpi_work(struct work_struct *work)
@@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work)
        struct mbox_params *mbcp = &mbc;
        int err = 0;
 
-       rtnl_lock();
+       mutex_lock(&qdev->mpi_mutex);
        /* Begin polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
 
@@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work)
 
        /* End polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
-       rtnl_unlock();
+       mutex_unlock(&qdev->mpi_mutex);
        ql_enable_completion_interrupt(qdev, 0);
 }
 
index 4c4d16905efb7253a055978e736edc93381cdd69..53b13deade9528539ea2dcaf5fe268b0e1ceabda 100644 (file)
@@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
        mdio_write(ioaddr, MII_BMCR, val & 0xffff);
 }
 
-static void rtl8169_check_link_status(struct net_device *dev,
+static void __rtl8169_check_link_status(struct net_device *dev,
                                      struct rtl8169_private *tp,
-                                     void __iomem *ioaddr)
+                                     void __iomem *ioaddr,
+                                     bool pm)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&tp->lock, flags);
        if (tp->link_ok(ioaddr)) {
                /* This is to cancel a scheduled suspend if there's one. */
-               pm_request_resume(&tp->pci_dev->dev);
+               if (pm)
+                       pm_request_resume(&tp->pci_dev->dev);
                netif_carrier_on(dev);
                netif_info(tp, ifup, dev, "link up\n");
        } else {
                netif_carrier_off(dev);
                netif_info(tp, ifdown, dev, "link down\n");
-               pm_schedule_suspend(&tp->pci_dev->dev, 100);
+               if (pm)
+                       pm_schedule_suspend(&tp->pci_dev->dev, 100);
        }
        spin_unlock_irqrestore(&tp->lock, flags);
 }
 
+static void rtl8169_check_link_status(struct net_device *dev,
+                                     struct rtl8169_private *tp,
+                                     void __iomem *ioaddr)
+{
+       __rtl8169_check_link_status(dev, tp, ioaddr, false);
+}
+
 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
 
 static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
@@ -4440,8 +4450,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);
@@ -4601,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                }
 
                if (status & LinkChg)
-                       rtl8169_check_link_status(dev, tp, ioaddr);
+                       __rtl8169_check_link_status(dev, tp, ioaddr, true);
 
                /* We need to see the lastest version of tp->intr_mask to
                 * avoid ignoring an MSI interrupt and having to wait for
@@ -4891,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
 
-       if (!tp->TxDescArray)
-               return 0;
-
-       rtl8169_check_link_status(dev, tp, tp->mmio_addr);
-       return -EBUSY;
+       return tp->TxDescArray ? -EBUSY : 0;
 }
 
 static const struct dev_pm_ops rtl8169_pm_ops = {
index 05df20e47976cb3965c59c5b227e67877bd2d0c4..fb83cdd946436561dbe645f5d742317fea8cfe91 100644 (file)
@@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
 
 static void efx_remove_channels(struct efx_nic *efx);
 static void efx_remove_port(struct efx_nic *efx);
+static void efx_init_napi(struct efx_nic *efx);
 static void efx_fini_napi(struct efx_nic *efx);
+static void efx_fini_napi_channel(struct efx_channel *channel);
 static void efx_fini_struct(struct efx_nic *efx);
 static void efx_start_all(struct efx_nic *efx);
 static void efx_stop_all(struct efx_nic *efx);
@@ -335,8 +337,10 @@ void efx_process_channel_now(struct efx_channel *channel)
 
        /* Disable interrupts and wait for ISRs to complete */
        efx_nic_disable_interrupts(efx);
-       if (efx->legacy_irq)
+       if (efx->legacy_irq) {
                synchronize_irq(efx->legacy_irq);
+               efx->legacy_irq_enabled = false;
+       }
        if (channel->irq)
                synchronize_irq(channel->irq);
 
@@ -351,6 +355,8 @@ void efx_process_channel_now(struct efx_channel *channel)
        efx_channel_processed(channel);
 
        napi_enable(&channel->napi_str);
+       if (efx->legacy_irq)
+               efx->legacy_irq_enabled = true;
        efx_nic_enable_interrupts(efx);
 }
 
@@ -426,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
 
                *channel = *old_channel;
 
+               channel->napi_dev = NULL;
                memset(&channel->eventq, 0, sizeof(channel->eventq));
 
                rx_queue = &channel->rx_queue;
@@ -736,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
        if (rc)
                goto rollback;
 
+       efx_init_napi(efx);
+
        /* Destroy old channels */
-       for (i = 0; i < efx->n_channels; i++)
+       for (i = 0; i < efx->n_channels; i++) {
+               efx_fini_napi_channel(other_channel[i]);
                efx_remove_channel(other_channel[i]);
+       }
 out:
        /* Free unused channel structures */
        for (i = 0; i < efx->n_channels; i++)
@@ -1400,6 +1411,8 @@ static void efx_start_all(struct efx_nic *efx)
                efx_start_channel(channel);
        }
 
+       if (efx->legacy_irq)
+               efx->legacy_irq_enabled = true;
        efx_nic_enable_interrupts(efx);
 
        /* Switch to event based MCDI completions after enabling interrupts.
@@ -1460,8 +1473,10 @@ static void efx_stop_all(struct efx_nic *efx)
 
        /* Disable interrupts and wait for ISR to complete */
        efx_nic_disable_interrupts(efx);
-       if (efx->legacy_irq)
+       if (efx->legacy_irq) {
                synchronize_irq(efx->legacy_irq);
+               efx->legacy_irq_enabled = false;
+       }
        efx_for_each_channel(channel, efx) {
                if (channel->irq)
                        synchronize_irq(channel->irq);
@@ -1593,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
  *
  **************************************************************************/
 
-static int efx_init_napi(struct efx_nic *efx)
+static void efx_init_napi(struct efx_nic *efx)
 {
        struct efx_channel *channel;
 
@@ -1602,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx)
                netif_napi_add(channel->napi_dev, &channel->napi_str,
                               efx_poll, napi_weight);
        }
-       return 0;
+}
+
+static void efx_fini_napi_channel(struct efx_channel *channel)
+{
+       if (channel->napi_dev)
+               netif_napi_del(&channel->napi_str);
+       channel->napi_dev = NULL;
 }
 
 static void efx_fini_napi(struct efx_nic *efx)
 {
        struct efx_channel *channel;
 
-       efx_for_each_channel(channel, efx) {
-               if (channel->napi_dev)
-                       netif_napi_del(&channel->napi_str);
-               channel->napi_dev = NULL;
-       }
+       efx_for_each_channel(channel, efx)
+               efx_fini_napi_channel(channel);
 }
 
 /**************************************************************************
@@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
        if (rc)
                goto fail1;
 
-       rc = efx_init_napi(efx);
-       if (rc)
-               goto fail2;
+       efx_init_napi(efx);
 
        rc = efx->type->init(efx);
        if (rc) {
@@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx)
        efx->type->fini(efx);
  fail3:
        efx_fini_napi(efx);
- fail2:
        efx_remove_all(efx);
  fail1:
        return rc;
index 0a7e26d73b525b13aba1fc9e234d38a699322f2a..b137c889152b14be6486fe9271f00658f81df031 100644 (file)
@@ -621,6 +621,7 @@ struct efx_filter_state;
  * @pci_dev: The PCI device
  * @type: Controller type attributes
  * @legacy_irq: IRQ number
+ * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)?
  * @workqueue: Workqueue for port reconfigures and the HW monitor.
  *     Work items do not hold and must not acquire RTNL.
  * @workqueue_name: Name of workqueue
@@ -709,6 +710,7 @@ struct efx_nic {
        struct pci_dev *pci_dev;
        const struct efx_nic_type *type;
        int legacy_irq;
+       bool legacy_irq_enabled;
        struct workqueue_struct *workqueue;
        char workqueue_name[16];
        struct work_struct reset_work;
index 41c36b9a4244b907907936b0a6abeaf8f2a301d1..67cb0c96838caeee1bc0497266ef51dd8e9bb407 100644 (file)
@@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
        u32 queues;
        int syserr;
 
+       /* Could this be ours?  If interrupts are disabled then the
+        * channel state may not be valid.
+        */
+       if (!efx->legacy_irq_enabled)
+               return result;
+
        /* Read the ISR which also ACKs the interrupts */
        efx_readd(efx, &reg, FR_BZ_INT_ISR0);
        queues = EFX_EXTRACT_DWORD(reg, 0, 31);
index 06bc6034ce810f49a67a698af524bec91e1eee5f..2114837809e76707e69f41cde38b0a0856ee745a 100644 (file)
@@ -1509,6 +1509,8 @@ static int stmmac_probe(struct net_device *dev)
                pr_warning("\tno valid MAC address;"
                        "please, use ifconfig or nwhwconfig!\n");
 
+       spin_lock_init(&priv->lock);
+
        ret = register_netdev(dev);
        if (ret) {
                pr_err("%s: ERROR %i registering the device\n",
@@ -1520,8 +1522,6 @@ static int stmmac_probe(struct net_device *dev)
            dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
            (dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
 
-       spin_lock_init(&priv->lock);
-
        return ret;
 }
 
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 a9f7d5d1a2695f95a968001a93c1449b9ac998be..7064e035757a16b927d35aa61991268089275744 100644 (file)
@@ -688,9 +688,6 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
 
        DMFE_DBUG(0, "dmfe_start_xmit", 0);
 
-       /* Resource flag check */
-       netif_stop_queue(dev);
-
        /* Too large packet check */
        if (skb->len > MAX_PACKET_SIZE) {
                pr_err("big packet = %d\n", (u16)skb->len);
@@ -698,6 +695,9 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
                return NETDEV_TX_OK;
        }
 
+       /* Resource flag check */
+       netif_stop_queue(dev);
+
        spin_lock_irqsave(&db->lock, flags);
 
        /* No Tx resource check, it never happen nromally */
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..812edf85d6d32b017454f449f4d03e300ed4ec50 100644 (file)
@@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
                                /* Packet is complete. Inject into stack. */
                                /* We have IP packet here */
                                odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
-                               /* don't check it */
-                               odev->skb_rx_buf->ip_summed =
-                                       CHECKSUM_UNNECESSARY;
-
                                skb_reset_mac_header(odev->skb_rx_buf);
 
                                /* Ship it off to the kernel */
@@ -2994,12 +2990,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 ea476cbd38b511039c8cb21ecdba7c61c1071ff1..e305274f83fba70c4967b2af57934ec5347a7eea 100644 (file)
@@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port)
        struct net_device *dev = port->netdev;
        card_t* card = port->card;
        u8 stat;
+       unsigned count = 0;
 
        spin_lock(&port->lock);
 
@@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port)
                        dev->stats.tx_bytes += readw(&desc->len);
                }
                writeb(0, &desc->stat); /* Free descriptor */
+               count++;
                port->txlast = (port->txlast + 1) % card->tx_ring_buffers;
        }
 
-       netif_wake_queue(dev);
+       if (count)
+               netif_wake_queue(dev);
        spin_unlock(&port->lock);
 }
 
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 8251946842e6186bddcd1cac303dbaea74664410..42ed923cdb1aad9479be7ed5f68a2b40c665ffcb 100644 (file)
@@ -1917,7 +1917,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
                sc->bmisscount = 0;
        }
 
-       if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+       if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT) {
                u64 tsf = ath5k_hw_get_tsf64(ah);
                u32 tsftu = TSF_TO_TU(tsf);
                int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
@@ -1949,8 +1950,9 @@ ath5k_beacon_send(struct ath5k_softc *sc)
                /* NB: hw still stops DMA, so proceed */
        }
 
-       /* refresh the beacon for AP mode */
-       if (sc->opmode == NL80211_IFTYPE_AP)
+       /* refresh the beacon for AP or MESH mode */
+       if (sc->opmode == NL80211_IFTYPE_AP ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT)
                ath5k_beacon_update(sc->hw, vif);
 
        ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
@@ -2851,7 +2853,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
 
        /* Assign the vap/adhoc to a beacon xmit slot. */
        if ((avf->opmode == NL80211_IFTYPE_AP) ||
-           (avf->opmode == NL80211_IFTYPE_ADHOC)) {
+           (avf->opmode == NL80211_IFTYPE_ADHOC) ||
+           (avf->opmode == NL80211_IFTYPE_MESH_POINT)) {
                int slot;
 
                WARN_ON(list_empty(&sc->bcbuf));
@@ -2870,7 +2873,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
                sc->bslot[avf->bslot] = vif;
                if (avf->opmode == NL80211_IFTYPE_AP)
                        sc->num_ap_vifs++;
-               else
+               else if (avf->opmode == NL80211_IFTYPE_ADHOC)
                        sc->num_adhoc_vifs++;
        }
 
index c4182359bee46603cffc46e9781750087f2a5f0f..a7b82f0085d2e899da46f6139dcac2185b42f924 100644 (file)
@@ -55,6 +55,8 @@
 #define SUB_NUM_CTL_MODES_AT_5G_40 2    /* excluding HT40, EXT-OFDM */
 #define SUB_NUM_CTL_MODES_AT_2G_40 3    /* excluding HT40, EXT-OFDM, EXT-CCK */
 
+#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
+
 static const struct ar9300_eeprom ar9300_default = {
        .eepromVersion = 2,
        .templateVersion = 2,
@@ -290,20 +292,21 @@ static const struct ar9300_eeprom ar9300_default = {
                }
         },
        .ctlPowerData_2G = {
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
 
-                { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
 
-                { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
 
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
         },
        .modalHeader5G = {
                /* 4 idle,t1,t2,b (4 bits per setting) */
@@ -568,56 +571,56 @@ static const struct ar9300_eeprom ar9300_default = {
        .ctlPowerData_5G = {
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 0}, {60, 1}, {60, 0}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
                        }
                },
                {
                        {
-                               {60, 0}, {60, 1}, {60, 1}, {60, 0},
-                               {60, 1}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
-                               {60, 0}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 0}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 0}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 0}, {60, 1},
+                               CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
                        }
                },
         }
@@ -1827,9 +1830,9 @@ static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
        struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
 
        if (is2GHz)
-               return ctl_2g[idx].ctlEdges[edge].tPower;
+               return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
        else
-               return ctl_5g[idx].ctlEdges[edge].tPower;
+               return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
 }
 
 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
@@ -1847,12 +1850,12 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
 
        if (is2GHz) {
                if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
-                   ctl_2g[idx].ctlEdges[edge - 1].flag)
-                       return ctl_2g[idx].ctlEdges[edge - 1].tPower;
+                   CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
+                       return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
        } else {
                if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
-                   ctl_5g[idx].ctlEdges[edge - 1].flag)
-                       return ctl_5g[idx].ctlEdges[edge - 1].tPower;
+                   CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
+                       return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
        }
 
        return AR9300_MAX_RATE_POWER;
index 3c533bb983c72859c9fbea4563070f387747506e..655b3033396c7f89ce1585479afb918102f993ae 100644 (file)
@@ -261,17 +261,12 @@ struct cal_tgt_pow_ht {
        u8 tPow2x[14];
 } __packed;
 
-struct cal_ctl_edge_pwr {
-       u8 tPower:6,
-          flag:2;
-} __packed;
-
 struct cal_ctl_data_2g {
-       struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G];
+       u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G];
 } __packed;
 
 struct cal_ctl_data_5g {
-       struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+       u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
 } __packed;
 
 struct ar9300_eeprom {
index 170d44a35ccbd2ca06886be2be2ed8c1cd5dcf25..0963071e8f908c15ebec8131c84b792d931e56d9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/leds.h>
 #include <linux/completion.h>
+#include <linux/pm_qos_params.h>
 
 #include "debug.h"
 #include "common.h"
@@ -328,7 +329,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
 int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
 void ath_draintxq(struct ath_softc *sc,
                     struct ath_txq *txq, bool retry_tx);
 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
@@ -646,6 +647,8 @@ struct ath_softc {
        struct ath_descdma txsdma;
 
        struct ath_ant_comb ant_comb;
+
+       struct pm_qos_request_list pm_qos_req;
 };
 
 struct ath_wiphy {
@@ -675,7 +678,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
 }
 
 extern struct ieee80211_ops ath9k_ops;
-extern struct pm_qos_request_list ath9k_pm_qos_req;
 extern int modparam_nohwcrypt;
 extern int led_blink;
 
index 1266333f586d8f574cf8fcda7086f036f3d56403..2bbf94d0191edb0ddc84084a37b07172203f2485 100644 (file)
@@ -240,16 +240,16 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
        for (i = 0; (i < num_band_edges) &&
                     (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
                if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
-                       twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+                       twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
                        break;
                } else if ((i > 0) &&
                           (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
                                                      is2GHz))) {
                        if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
                                               is2GHz) < freq &&
-                           pRdEdgesPower[i - 1].flag) {
+                           CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
                                twiceMaxEdgePower =
-                                       pRdEdgesPower[i - 1].tPower;
+                                       CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
                        }
                        break;
                }
index dacb45e1b9063b620736475b6116975fcb60cf4d..dd59f09441a3cdf00cbc805a36e4734d58a04253 100644 (file)
 
 #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
 
+#define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f)
+#define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03)
+
+#define LNA_CTL_BUF_MODE       BIT(0)
+#define LNA_CTL_ISEL_LO                BIT(1)
+#define LNA_CTL_ISEL_HI                BIT(2)
+#define LNA_CTL_BUF_IN         BIT(3)
+#define LNA_CTL_FEM_BAND       BIT(4)
+#define LNA_CTL_LOCAL_BIAS     BIT(5)
+#define LNA_CTL_FORCE_XPA      BIT(6)
+#define LNA_CTL_USE_ANT1       BIT(7)
+
 enum eeprom_param {
        EEP_NFTHRESH_5,
        EEP_NFTHRESH_2,
@@ -378,10 +390,7 @@ struct modal_eep_header {
        u8 xatten2Margin[AR5416_MAX_CHAINS];
        u8 ob_ch1;
        u8 db_ch1;
-       u8 useAnt1:1,
-           force_xpaon:1,
-           local_bias:1,
-           femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+       u8 lna_ctl;
        u8 miscBits;
        u16 xpaBiasLvlFreq[3];
        u8 futureModal[6];
@@ -535,18 +544,10 @@ struct cal_target_power_ht {
        u8 tPow2x[8];
 } __packed;
 
-
-#ifdef __BIG_ENDIAN_BITFIELD
-struct cal_ctl_edges {
-       u8 bChannel;
-       u8 flag:2, tPower:6;
-} __packed;
-#else
 struct cal_ctl_edges {
        u8 bChannel;
-       u8 tPower:6, flag:2;
+       u8 ctl;
 } __packed;
-#endif
 
 struct cal_data_op_loop_ar9287 {
        u8 pwrPdg[2][5];
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 76b4d65472dd2b37dbf98ff69b57646e53443c61..a3ccb1b9638d7b8b44f32ba651d519d042b806ec 100644 (file)
@@ -451,9 +451,10 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
                ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
                                          AR_AN_TOP2_LOCALBIAS,
                                          AR_AN_TOP2_LOCALBIAS_S,
-                                         pModal->local_bias);
+                                         !!(pModal->lna_ctl &
+                                            LNA_CTL_LOCAL_BIAS));
                REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
-                             pModal->force_xpaon);
+                             !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
        }
 
        REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
@@ -1062,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
        case 1:
                break;
        case 2:
-               scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               else
+                       scaledPower = 0;
                break;
        case 3:
-               scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               else
+                       scaledPower = 0;
                break;
        }
 
-       scaledPower = max((u16)0, scaledPower);
-
        if (IS_CHAN_2GHZ(chan)) {
                numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
                        SUB_NUM_CTL_MODES_AT_2G_40;
@@ -1428,9 +1433,9 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
 
        num_ant_config = 1;
 
-       if (pBase->version >= 0x0E0D)
-               if (pModal->useAnt1)
-                       num_ant_config += 1;
+       if (pBase->version >= 0x0E0D &&
+           (pModal->lna_ctl & LNA_CTL_USE_ANT1))
+               num_ant_config += 1;
 
        return num_ant_config;
 }
index f7ec31b4ddd3a9af801dcb8211763f21e6ab7e09..0de3c3d3c245c2ad5f71f0a419a7ba4fab96e60c 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
@@ -1015,6 +1024,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
        struct hif_device_usb *hif_dev =
                (struct hif_device_usb *) usb_get_intfdata(interface);
 
+       /*
+        * The device has to be set to FULLSLEEP mode in case no
+        * interface is up.
+        */
+       if (!(hif_dev->flags & HIF_USB_START))
+               ath9k_htc_suspend(hif_dev->htc_handle);
+
        ath9k_hif_usb_dealloc_urbs(hif_dev);
 
        return 0;
index 75ecf6a30d25c6ac68d346c5ac862a0255ba4be1..c3b561daa6c1035a68f4b27da92914ba4e601399 100644 (file)
@@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv);
 void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
 void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
 void ath9k_ps_work(struct work_struct *work);
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+                       enum ath9k_power_mode mode);
 
 void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
 void ath9k_init_leds(struct ath9k_htc_priv *priv);
@@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
                           u16 devid, char *product);
 void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
 #ifdef CONFIG_PM
+void ath9k_htc_suspend(struct htc_target *htc_handle);
 int ath9k_htc_resume(struct htc_target *htc_handle);
 #endif
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
index 3d7b97f1b3aeebe5840c438b5ccf631de702d6c2..8776f49ffd41bf2a40f080798fe6c5173b80c9b4 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:
@@ -889,6 +891,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
 }
 
 #ifdef CONFIG_PM
+
+void ath9k_htc_suspend(struct htc_target *htc_handle)
+{
+       ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP);
+}
+
 int ath9k_htc_resume(struct htc_target *htc_handle)
 {
        int ret;
index 9a3be8da755d2f7181ada323e5ec9054b58a0a9e..51977caca47fd6d456e521cff4511e1079f2e09a 100644 (file)
@@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
        return mode;
 }
 
-static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
-                              enum ath9k_power_mode mode)
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+                       enum ath9k_power_mode mode)
 {
        bool ret;
 
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 6ebc68bca91f0a999614572b38f69452df49645d..c7fbe25cc12827cf29f68729fe636b07ef75ebfa 100644 (file)
@@ -2044,7 +2044,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
                val = REG_READ(ah, AR7010_GPIO_IN);
                return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0;
        } else if (AR_SREV_9300_20_OR_LATER(ah))
-               return MS_REG_READ(AR9300, gpio) != 0;
+               return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) &
+                       AR_GPIO_BIT(gpio)) != 0;
        else if (AR_SREV_9271(ah))
                return MS_REG_READ(AR9271, gpio) != 0;
        else if (AR_SREV_9287_11_OR_LATER(ah))
index 6a0d99eff404b77417856c7f1b7c035eb079359e..14b8ab386daff8823bcc3301fa52d467ce6cb01b 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/slab.h>
-#include <linux/pm_qos_params.h>
 
 #include "ath9k.h"
 
@@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = {
        .write = ath9k_iowrite32,
 };
 
-struct pm_qos_request_list ath9k_pm_qos_req;
-
 /**************************/
 /*     Initialization     */
 /**************************/
@@ -664,6 +661,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
        hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_P2P_GO) |
+               BIT(NL80211_IFTYPE_P2P_CLIENT) |
                BIT(NL80211_IFTYPE_AP) |
                BIT(NL80211_IFTYPE_WDS) |
                BIT(NL80211_IFTYPE_STATION) |
@@ -759,7 +758,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
        ath_init_leds(sc);
        ath_start_rfkill_poll(sc);
 
-       pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+       pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
                           PM_QOS_DEFAULT_VALUE);
 
        return 0;
@@ -817,8 +816,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 +829,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
        }
 
        ieee80211_unregister_hw(hw);
+       pm_qos_remove_request(&sc->pm_qos_req);
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
        ath9k_deinit_softc(sc);
index 8c13479b17cd9d418f7d7f496b01dbf7445ba202..c996963ab33927c027f3fb019200261c0ac07d18 100644 (file)
@@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
                        rs->rs_phyerr = phyerr;
                } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
                        rs->rs_status |= ATH9K_RXERR_DECRYPT;
-               else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
-                        rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
+               else if (ads.ds_rxstatus8 & AR_MichaelErr)
                        rs->rs_status |= ATH9K_RXERR_MIC;
                else if (ads.ds_rxstatus8 & AR_KeyMiss)
                        rs->rs_status |= ATH9K_RXERR_DECRYPT;
index 25d3ef4c338e1eb45800b45fec112fc064c095af..c0c3464d3a861162e1142a0e2931a73aedae1fab 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/nl80211.h>
-#include <linux/pm_qos_params.h>
 #include "ath9k.h"
 #include "btcoex.h"
 
@@ -245,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
         * the relevant bits of the h/w.
         */
        ath9k_hw_set_interrupts(ah, 0);
-       ath_drain_all_txq(sc, false);
+       stopped = ath_drain_all_txq(sc, false);
 
        spin_lock_bh(&sc->rx.pcu_lock);
 
-       stopped = ath_stoprecv(sc);
+       if (!ath_stoprecv(sc))
+               stopped = false;
 
        /* XXX: do not flush receive queue here. We don't want
         * to flush data frames already in queue because of
@@ -1244,7 +1244,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
                        ath9k_btcoex_timer_resume(sc);
        }
 
-       pm_qos_update_request(&ath9k_pm_qos_req, 55);
+       pm_qos_update_request(&sc->pm_qos_req, 55);
 
 mutex_unlock:
        mutex_unlock(&sc->mutex);
@@ -1423,7 +1423,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
        sc->sc_flags |= SC_OP_INVALID;
 
-       pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE);
+       pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
 
        mutex_unlock(&sc->mutex);
 
@@ -1520,7 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
        struct ath_softc *sc = aphy->sc;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_vif *avp = (void *)vif->drv_priv;
-       int i;
 
        ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
 
@@ -1534,21 +1533,24 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
        if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
            (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
            (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+               /* Disable SWBA interrupt */
+               sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
                ath9k_ps_wakeup(sc);
+               ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
                ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
                ath9k_ps_restore(sc);
+               tasklet_kill(&sc->bcon_tasklet);
        }
 
        ath_beacon_return(sc, avp);
        sc->sc_flags &= ~SC_OP_BEACONS;
 
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
-               if (sc->beacon.bslot[i] == vif) {
-                       printk(KERN_DEBUG "%s: vif had allocated beacon "
-                              "slot\n", __func__);
-                       sc->beacon.bslot[i] = NULL;
-                       sc->beacon.bslot_aphy[i] = NULL;
-               }
+       if (sc->nbcnvifs) {
+               /* Re-enable SWBA interrupt */
+               sc->sc_ah->imask |= ATH9K_INT_SWBA;
+               ath9k_ps_wakeup(sc);
+               ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+               ath9k_ps_restore(sc);
        }
 
        sc->nvifs--;
index c76ea53c20ce7dbe41863c00930853a59ccc6cf8..fdc2ec52b42fcd5647df2c967598e94bcfc13c9a 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);
 
@@ -838,6 +838,10 @@ static bool ath9k_rx_accept(struct ath_common *common,
                            struct ath_rx_status *rx_stats,
                            bool *decrypt_error)
 {
+#define is_mc_or_valid_tkip_keyix ((is_mc ||                   \
+               (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \
+               test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
+
        struct ath_hw *ah = common->ah;
        __le16 fc;
        u8 rx_status_len = ah->caps.rx_status_len;
@@ -879,15 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
                if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
                        *decrypt_error = true;
                } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
+                       bool is_mc;
                        /*
                         * The MIC error bit is only valid if the frame
                         * is not a control frame or fragment, and it was
                         * decrypted using a valid TKIP key.
                         */
+                       is_mc = !!is_multicast_ether_addr(hdr->addr1);
+
                        if (!ieee80211_is_ctl(fc) &&
                            !ieee80211_has_morefrags(fc) &&
                            !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
-                           test_bit(rx_stats->rs_keyix, common->tkip_keymap))
+                           is_mc_or_valid_tkip_keyix)
                                rxs->flag |= RX_FLAG_MMIC_ERROR;
                        else
                                rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
index fa05b711e5cdfb7657f94ac420bc87a3f443c1ef..2c6a22fbb0f0cf76fb5ac5cfd22b530402e9f693 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
@@ -978,11 +984,13 @@ enum {
 #define AR9287_GPIO_IN_VAL_S                     11
 #define AR9271_GPIO_IN_VAL                       0xFFFF0000
 #define AR9271_GPIO_IN_VAL_S                     16
-#define AR9300_GPIO_IN_VAL                       0x0001FFFF
-#define AR9300_GPIO_IN_VAL_S                     0
 #define AR7010_GPIO_IN_VAL                       0x0000FFFF
 #define AR7010_GPIO_IN_VAL_S                     0
 
+#define AR_GPIO_IN                              0x404c
+#define AR9300_GPIO_IN_VAL                       0x0001FFFF
+#define AR9300_GPIO_IN_VAL_S                     0
+
 #define AR_GPIO_OE_OUT                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
 #define AR_GPIO_OE_OUT_DRV                       0x3
 #define AR_GPIO_OE_OUT_DRV_NO                    0x0
index f2ade2402ce27709e1da385941b9adbaece96b1e..aff04789f794ee805bf50f1f13d28783f79851d3 100644 (file)
@@ -1120,7 +1120,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
        }
 }
 
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1128,7 +1128,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
        int i, npend = 0;
 
        if (sc->sc_flags & SC_OP_INVALID)
-               return;
+               return true;
 
        /* Stop beacon queue */
        ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
@@ -1142,25 +1142,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
                }
        }
 
-       if (npend) {
-               int r;
-
-               ath_print(common, ATH_DBG_FATAL,
-                         "Failed to stop TX DMA. Resetting hardware!\n");
-
-               spin_lock_bh(&sc->sc_resetlock);
-               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
-               if (r)
-                       ath_print(common, ATH_DBG_FATAL,
-                                 "Unable to reset hardware; reset status %d\n",
-                                 r);
-               spin_unlock_bh(&sc->sc_resetlock);
-       }
+       if (npend)
+               ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n");
 
        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
                if (ATH_TXQ_SETUP(sc, i))
                        ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
        }
+
+       return !npend;
 }
 
 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
index ae6c006bbc56c03bd76f0e1cc56c46a927db1db9..546b4e4ec5ea090aaf6ed0ce7b77ed024e3c8fd6 100644 (file)
@@ -291,7 +291,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
 
                if (SUPP(CARL9170FW_WLANTX_CAB)) {
                        ar->hw->wiphy->interface_modes |=
-                               BIT(NL80211_IFTYPE_AP);
+                               BIT(NL80211_IFTYPE_AP) |
+                               BIT(NL80211_IFTYPE_P2P_GO);
                }
        }
 
index 980ae70ea424f6dc50a93734446536588bea9734..dc7b30b170d037de1dc9b38b058458a98f8efb43 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--;
@@ -1631,7 +1631,8 @@ void *carl9170_alloc(size_t priv_size)
         * supports these modes. The code which will add the
         * additional interface_modes is in fw.c.
         */
-       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                    BIT(NL80211_IFTYPE_P2P_CLIENT);
 
        hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
                     IEEE80211_HW_REPORTS_TX_ACK_STATUS |
index b575c865142d64f82f8e072518c0de44e46039cc..7e6506a77bbb625a28ad0e6b41f7984607fe5f80 100644 (file)
@@ -810,7 +810,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
 
        mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
                              AR9170_TX_MAC_BACKOFF);
-       mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &&
+       mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &
                               AR9170_TX_MAC_QOS);
 
        no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
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 e5685dc317a80423a7acb6a68694bba4043d3897..b4de0ca10feb8f9ef18b826e00f82a240fb40e91 100644 (file)
@@ -1170,7 +1170,6 @@ static void if_sdio_remove(struct sdio_func *func)
        lbs_deb_sdio("call remove card\n");
        lbs_stop_card(card->priv);
        lbs_remove_card(card->priv);
-       card->priv->surpriseremoved = 1;
 
        flush_workqueue(card->workqueue);
        destroy_workqueue(card->workqueue);
index 79bcb4e5d2ca03c7ccb82621576296a6ea68b5d0..ecd4d04b2c3cea67aebd6d62c9446a3318a2840c 100644 (file)
@@ -1055,7 +1055,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
        lbs_stop_card(priv);
        lbs_remove_card(priv); /* will call free_netdev */
 
-       priv->surpriseremoved = 1;
        free_irq(spi->irq, card);
        if_spi_terminate_spi_thread(card);
        if (card->pdata->teardown)
index 46b88b118c992c12764084233f8633a62a01a629..fcd1bbfc632d527364b8f1fc91abd70ba3242225 100644 (file)
@@ -915,8 +915,6 @@ void lbs_remove_card(struct lbs_private *priv)
 
        lbs_free_adapter(priv);
        lbs_cfg_free(priv);
-
-       priv->dev = NULL;
        free_netdev(dev);
 
        lbs_deb_leave(LBS_DEB_MAIN);
index e8e2d0f4763db4f33e899ad712595d9af5173333..f3d396e7544b9d1d0f7848bc1cabb74bce75b8de 100644 (file)
@@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work)
                                orinoco_add_hostscan_results(priv, buf, len);
 
                        kfree(buf);
-               } else if (priv->scan_request) {
+               } else {
                        /* Either abort or complete the scan */
-                       cfg80211_scan_done(priv->scan_request, (len < 0));
-                       priv->scan_request = NULL;
+                       orinoco_scan_done(priv, (len < 0));
                }
 
                spin_lock_irqsave(&priv->scan_lock, flags);
@@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv)
                hermes_write_regn(hw, EVACK, 0xffff);
        }
 
+       orinoco_scan_done(priv, true);
+
        /* firmware will have to reassociate */
        netif_carrier_off(dev);
        priv->last_linkstatus = 0xffff;
@@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work)
        orinoco_unlock(priv, &flags);
 
        /* Scanning support: Notify scan cancellation */
-       if (priv->scan_request) {
-               cfg80211_scan_done(priv->scan_request, 1);
-               priv->scan_request = NULL;
-       }
+       orinoco_scan_done(priv, true);
 
        if (priv->hard_reset) {
                err = (*priv->hard_reset)(priv);
@@ -1813,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv)
        struct net_device *dev = priv->ndev;
        int err = 0;
 
+       /* If we've called commit, we are reconfiguring or bringing the
+        * interface up. Maintaining countermeasures across this would
+        * be confusing, so note that we've disabled them. The port will
+        * be enabled later in orinoco_commit or __orinoco_up. */
+       priv->tkip_cm_active = 0;
+
        err = orinoco_hw_program_rids(priv);
 
        /* FIXME: what about netif_tx_lock */
index 71b3d68b9403a8c4c142b776179c1edef9328ebd..32954c4b243a9dc70bbb0fd350c6c79ff67875d3 100644 (file)
@@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link)
                goto failed;
        }
 
-       ret = pcmcia_request_irq(link, orinoco_interrupt);
-       if (ret)
-               goto failed;
-
-       /* We initialize the hermes structure before completing PCMCIA
-        * configuration just in case the interrupt handler gets
-        * called. */
        mem = ioport_map(link->resource[0]->start,
                        resource_size(link->resource[0]));
        if (!mem)
                goto failed;
 
+       /* We initialize the hermes structure before completing PCMCIA
+        * configuration just in case the interrupt handler gets
+        * called. */
        hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
 
+       ret = pcmcia_request_irq(link, orinoco_interrupt);
+       if (ret)
+               goto failed;
+
        ret = pcmcia_enable_device(link);
        if (ret)
                goto failed;
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 4300d9db7d8caab2d70442b7cbd37a9da69adef9..86cb54c842e745ffd7863457f23f45185440f556 100644 (file)
@@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv,
                priv->scan_request = NULL;
        }
 }
+
+void orinoco_scan_done(struct orinoco_private *priv, bool abort)
+{
+       if (priv->scan_request) {
+               cfg80211_scan_done(priv->scan_request, abort);
+               priv->scan_request = NULL;
+       }
+}
index 2dc4e046dbdb61c5c19f33e14f6ae4fae381a8c9..27281fb0a6dc02f529b4ea1edf2fb29e2a6903be 100644 (file)
@@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
 void orinoco_add_hostscan_results(struct orinoco_private *dev,
                                  unsigned char *buf,
                                  size_t len);
+void orinoco_scan_done(struct orinoco_private *priv, bool abort);
 
 #endif /* _ORINOCO_SCAN_H_ */
index fb859a5ad2eb8a5c2e02f349cf4002caac32fc49..db34c282e59b39340a9bf7c6c51f529bf020a1c0 100644 (file)
@@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link)
                goto failed;
        }
 
-       ret = pcmcia_request_irq(link, orinoco_interrupt);
-       if (ret)
-               goto failed;
-
-       /* We initialize the hermes structure before completing PCMCIA
-        * configuration just in case the interrupt handler gets
-        * called. */
        mem = ioport_map(link->resource[0]->start,
                        resource_size(link->resource[0]));
        if (!mem)
                goto failed;
 
+       /* We initialize the hermes structure before completing PCMCIA
+        * configuration just in case the interrupt handler gets
+        * called. */
        hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
        hw->eeprom_pda = true;
 
+       ret = pcmcia_request_irq(link, orinoco_interrupt);
+       if (ret)
+               goto failed;
+
        ret = pcmcia_enable_device(link);
        if (ret)
                goto failed;
index 93505f93bf97711019e86bbe27f39f4f727bce01..e5afabee60d1834b898193479cf710c3bb3eed22 100644 (file)
@@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
                 */
                if (param->value) {
                        priv->tkip_cm_active = 1;
-                       ret = hermes_enable_port(hw, 0);
+                       ret = hermes_disable_port(hw, 0);
                } else {
                        priv->tkip_cm_active = 0;
-                       ret = hermes_disable_port(hw, 0);
+                       ret = hermes_enable_port(hw, 0);
                }
                break;
 
index 458bb57914a32d57948ff425508f6b40ac2de7e1..cdbeec9f83ea256507c57762dda8a7f73e69983e 100644 (file)
@@ -66,8 +66,8 @@ struct netfront_cb {
 
 #define GRANT_INVALID_REF      0
 
-#define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE)
-#define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE)
+#define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
+#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
 #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
 
 struct netfront_info {
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 2d73dfcecdbb4e2098e3d881a6a091a9e8ca5e62..57313f4658bc55a00a5a7d36fbb86450f8144def 100644 (file)
@@ -180,7 +180,7 @@ struct pnp_protocol pnpacpi_protocol = {
 };
 EXPORT_SYMBOL(pnpacpi_protocol);
 
-static char *pnpacpi_get_id(struct acpi_device *device)
+static char *__init pnpacpi_get_id(struct acpi_device *device)
 {
        struct acpi_hardware_id *id;
 
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 51237fbb1bbb7e15f952296a9ffcb9f668418fc9..6d20b0454a1d7284c7728e3ec0c85d7d8e22f452 100644 (file)
@@ -231,8 +231,7 @@ static int tps6586x_dvm_voltages[] = {
 };
 
 #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits,       \
-                          ereg0, ebit0, ereg1, ebit1, goreg, gobit)    \
-{                                                                      \
+                          ereg0, ebit0, ereg1, ebit1)                  \
        .desc   = {                                                     \
                .name   = "REG-" #_id,                                  \
                .ops    = &tps6586x_regulator_##_ops,                   \
@@ -248,18 +247,26 @@ static int tps6586x_dvm_voltages[] = {
        .enable_bit[0]  = (ebit0),                                      \
        .enable_reg[1]  = TPS6586X_SUPPLY##ereg1,                       \
        .enable_bit[1]  = (ebit1),                                      \
-       .voltages       = tps6586x_##vdata##_voltages,                  \
-}
+       .voltages       = tps6586x_##vdata##_voltages,
+
+#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                     \
+       .go_reg = TPS6586X_##goreg,                                     \
+       .go_bit = (gobit),
 
 #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits,                   \
                     ereg0, ebit0, ereg1, ebit1)                        \
+{                                                                      \
        TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits,     \
-                          ereg0, ebit0, ereg1, ebit1, 0, 0)
+                          ereg0, ebit0, ereg1, ebit1)                  \
+}
 
 #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits,                   \
                     ereg0, ebit0, ereg1, ebit1, goreg, gobit)          \
+{                                                                      \
        TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits,     \
-                          ereg0, ebit0, ereg1, ebit1, goreg, gobit)
+                          ereg0, ebit0, ereg1, ebit1)                  \
+       TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                      \
+}
 
 static struct tps6586x_regulator tps6586x_regulator[] = {
        TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0),
@@ -267,11 +274,11 @@ static struct tps6586x_regulator tps6586x_regulator[] = {
        TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
        TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
        TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
-       TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6),
+       TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
        TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
-       TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7),
+       TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
        TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
-       TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1),
+       TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
 
        TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6),
        TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6),
@@ -290,6 +297,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
        uint8_t val1, val2;
        int ret;
 
+       if (ri->enable_reg[0] == ri->enable_reg[1] &&
+           ri->enable_bit[0] == ri->enable_bit[1])
+                       return 0;
+
        ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
        if (ret)
                return ret;
@@ -298,14 +309,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
        if (ret)
                return ret;
 
-       if (!(val2 & ri->enable_bit[1]))
+       if (!(val2 & (1 << ri->enable_bit[1])))
                return 0;
 
        /*
         * The regulator is on, but it's enabled with the bit we don't
         * want to use, so we switch the enable bits
         */
-       if (!(val1 & ri->enable_bit[0])) {
+       if (!(val1 & (1 << ri->enable_bit[0]))) {
                ret = tps6586x_set_bits(parent, ri->enable_reg[0],
                                        1 << ri->enable_bit[0]);
                if (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 044fb22718d22c8371bd64b588ad044031415e7f..51c666fb67a4c479b99f8a7d9d3e7e635d2107fe 100644 (file)
@@ -45,8 +45,8 @@ static char *init_device;
 module_param_named(device, init_device, charp, 0400);
 MODULE_PARM_DESC(device, "specify initial device");
 
-static struct kmem_cache *zfcp_cache_hw_align(const char *name,
-                                             unsigned long size)
+static struct kmem_cache * __init zfcp_cache_hw_align(const char *name,
+                                                     unsigned long size)
 {
        return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL);
 }
@@ -311,8 +311,7 @@ int zfcp_status_read_refill(struct zfcp_adapter *adapter)
                if (zfcp_fsf_status_read(adapter->qdio)) {
                        if (atomic_read(&adapter->stat_miss) >=
                            adapter->stat_read_buf_num) {
-                               zfcp_erp_adapter_reopen(adapter, 0, "axsref1",
-                                                       NULL);
+                               zfcp_erp_adapter_reopen(adapter, 0, "axsref1");
                                return 1;
                        }
                        break;
@@ -459,7 +458,7 @@ void zfcp_adapter_unregister(struct zfcp_adapter *adapter)
        sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs);
 
        zfcp_erp_thread_kill(adapter);
-       zfcp_dbf_adapter_unregister(adapter->dbf);
+       zfcp_dbf_adapter_unregister(adapter);
        zfcp_qdio_destroy(adapter->qdio);
 
        zfcp_ccw_adapter_put(adapter); /* final put to release */
index 0833c2b51e39b3ac5af682a0b05e8f1fd9c83192..4f7852dd30c7723c78c9409a07dfd05329f09ac0 100644 (file)
@@ -48,7 +48,7 @@ static int zfcp_ccw_activate(struct ccw_device *cdev)
 
        zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
        zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
-                               "ccresu2", NULL);
+                               "ccresu2");
        zfcp_erp_wait(adapter);
        flush_work(&adapter->scan_work);
 
@@ -182,7 +182,7 @@ static int zfcp_ccw_set_offline(struct ccw_device *cdev)
        if (!adapter)
                return 0;
 
-       zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
+       zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
        zfcp_erp_wait(adapter);
 
        zfcp_ccw_adapter_put(adapter);
@@ -207,24 +207,24 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
        switch (event) {
        case CIO_GONE:
                dev_warn(&cdev->dev, "The FCP device has been detached\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
+               zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
                break;
        case CIO_NO_PATH:
                dev_warn(&cdev->dev,
                         "The CHPID for the FCP device is offline\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
+               zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
                break;
        case CIO_OPER:
                dev_info(&cdev->dev, "The FCP device is operational again\n");
                zfcp_erp_set_adapter_status(adapter,
                                            ZFCP_STATUS_COMMON_RUNNING);
                zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
-                                       "ccnoti4", NULL);
+                                       "ccnoti4");
                break;
        case CIO_BOXED:
                dev_warn(&cdev->dev, "The FCP device did not respond within "
                                     "the specified time\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
+               zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
                break;
        }
 
@@ -243,7 +243,7 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
        if (!adapter)
                return;
 
-       zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
+       zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
        zfcp_erp_wait(adapter);
        zfcp_erp_thread_kill(adapter);
 
index d692e229ecba59c03549fc19447e81d8184503da..46342fee394d5d96b2eaf643a0323f8a760b1381 100644 (file)
@@ -288,7 +288,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
                    (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
                        zfcp_erp_port_reopen(port,
                                             ZFCP_STATUS_COMMON_ERP_FAILED,
-                                            "cfaac_1", NULL);
+                                            "cfaac_1");
        }
        read_unlock_irqrestore(&adapter->port_list_lock, flags);
 
@@ -299,7 +299,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
                    (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
                        zfcp_erp_lun_reopen(sdev,
                                            ZFCP_STATUS_COMMON_ERP_FAILED,
-                                           "cfaac_2", NULL);
+                                           "cfaac_2");
        }
 }
 
@@ -426,7 +426,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev,
                        zfcp_scsi_dev_lun(sdev),
                        (unsigned long long)zfcp_sdev->port->wwpn);
                zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
-               zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL);
+               zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6");
                return -EACCES;
        }
 
@@ -437,7 +437,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev,
                        zfcp_scsi_dev_lun(sdev),
                        (unsigned long long)zfcp_sdev->port->wwpn);
                zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
-               zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL);
+               zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8");
                return -EACCES;
        }
 
index 2cdd6b28ff7fd1f006663277301f5cbc0e49271a..96d1462e0bf5bddc8719e603702afb491981df3c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Debug traces for zfcp.
  *
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -22,980 +22,392 @@ module_param(dbfsize, uint, 0400);
 MODULE_PARM_DESC(dbfsize,
                 "number of pages for each debug feature area (default 4)");
 
-static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
-                            int level, char *from, int from_len)
+static inline unsigned int zfcp_dbf_plen(unsigned int offset)
 {
-       int offset;
-       struct zfcp_dbf_dump *dump = to;
-       int room = to_len - sizeof(*dump);
-
-       for (offset = 0; offset < from_len; offset += dump->size) {
-               memset(to, 0, to_len);
-               strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
-               dump->total_size = from_len;
-               dump->offset = offset;
-               dump->size = min(from_len - offset, room);
-               memcpy(dump->data, from + offset, dump->size);
-               debug_event(dbf, level, dump, dump->size + sizeof(*dump));
-       }
+       return sizeof(struct zfcp_dbf_pay) + offset - ZFCP_DBF_PAY_MAX_REC;
 }
 
-static void zfcp_dbf_tag(char **p, const char *label, const char *tag)
+static inline
+void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area,
+                      u64 req_id)
 {
-       int i;
-
-       *p += sprintf(*p, "%-24s", label);
-       for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
-               *p += sprintf(*p, "%c", tag[i]);
-       *p += sprintf(*p, "\n");
-}
+       struct zfcp_dbf_pay *pl = &dbf->pay_buf;
+       u16 offset = 0, rec_length;
 
-static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2)
-{
-       *buf += sprintf(*buf, "%-24s%s\n", s1, s2);
-}
+       spin_lock(&dbf->pay_lock);
+       memset(pl, 0, sizeof(*pl));
+       pl->fsf_req_id = req_id;
+       memcpy(pl->area, area, ZFCP_DBF_TAG_LEN);
 
-static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...)
-{
-       va_list arg;
+       while (offset < length) {
+               rec_length = min((u16) ZFCP_DBF_PAY_MAX_REC,
+                                (u16) (length - offset));
+               memcpy(pl->data, data + offset, rec_length);
+               debug_event(dbf->pay, 1, pl, zfcp_dbf_plen(rec_length));
 
-       *buf += sprintf(*buf, "%-24s", s);
-       va_start(arg, format);
-       *buf += vsprintf(*buf, format, arg);
-       va_end(arg);
-       *buf += sprintf(*buf, "\n");
-}
-
-static void zfcp_dbf_outd(char **p, const char *label, char *buffer,
-                         int buflen, int offset, int total_size)
-{
-       if (!offset)
-               *p += sprintf(*p, "%-24s  ", label);
-       while (buflen--) {
-               if (offset > 0) {
-                       if ((offset % 32) == 0)
-                               *p += sprintf(*p, "\n%-24c  ", ' ');
-                       else if ((offset % 4) == 0)
-                               *p += sprintf(*p, " ");
-               }
-               *p += sprintf(*p, "%02x", *buffer++);
-               if (++offset == total_size) {
-                       *p += sprintf(*p, "\n");
-                       break;
-               }
+               offset += rec_length;
+               pl->counter++;
        }
-       if (!total_size)
-               *p += sprintf(*p, "\n");
-}
 
-static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view,
-                               int area, debug_entry_t *entry, char *out_buf)
-{
-       struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);
-       struct timespec t;
-       char *p = out_buf;
-
-       if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
-               stck_to_timespec(entry->id.stck, &t);
-               zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu",
-                            t.tv_sec, t.tv_nsec);
-               zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid);
-       } else  {
-               zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset,
-                             dump->total_size);
-               if ((dump->offset + dump->size) == dump->total_size)
-                       p += sprintf(p, "\n");
-       }
-       return p - out_buf;
+       spin_unlock(&dbf->pay_lock);
 }
 
-void _zfcp_dbf_hba_fsf_response(const char *tag2, int level,
-                               struct zfcp_fsf_req *fsf_req,
-                               struct zfcp_dbf *dbf)
+/**
+ * zfcp_dbf_hba_fsf_res - trace event for fsf responses
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @req: request for which a response was received
+ */
+void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req)
 {
-       struct fsf_qtcb *qtcb = fsf_req->qtcb;
-       union fsf_prot_status_qual *prot_status_qual =
-                                       &qtcb->prefix.prot_status_qual;
-       union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;
-       struct scsi_cmnd *scsi_cmnd;
-       struct zfcp_port *port;
-       struct zfcp_unit *unit;
-       struct zfcp_send_els *send_els;
-       struct zfcp_dbf_hba_record *rec = &dbf->hba_buf;
-       struct zfcp_dbf_hba_record_response *response = &rec->u.response;
+       struct zfcp_dbf *dbf = req->adapter->dbf;
+       struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix;
+       struct fsf_qtcb_header *q_head = &req->qtcb->header;
+       struct zfcp_dbf_hba *rec = &dbf->hba_buf;
        unsigned long flags;
 
        spin_lock_irqsave(&dbf->hba_lock, flags);
        memset(rec, 0, sizeof(*rec));
-       strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);
-       strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
-
-       response->fsf_command = fsf_req->fsf_command;
-       response->fsf_reqid = fsf_req->req_id;
-       response->fsf_seqno = fsf_req->seq_no;
-       response->fsf_issued = fsf_req->issued;
-       response->fsf_prot_status = qtcb->prefix.prot_status;
-       response->fsf_status = qtcb->header.fsf_status;
-       memcpy(response->fsf_prot_status_qual,
-              prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE);
-       memcpy(response->fsf_status_qual,
-              fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
-       response->fsf_req_status = fsf_req->status;
-       response->sbal_first = fsf_req->qdio_req.sbal_first;
-       response->sbal_last = fsf_req->qdio_req.sbal_last;
-       response->sbal_response = fsf_req->qdio_req.sbal_response;
-       response->pool = fsf_req->pool != NULL;
-       response->erp_action = (unsigned long)fsf_req->erp_action;
-
-       switch (fsf_req->fsf_command) {
-       case FSF_QTCB_FCP_CMND:
-               if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
-                       break;
-               scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
-               if (scsi_cmnd) {
-                       response->u.fcp.cmnd = (unsigned long)scsi_cmnd;
-                       response->u.fcp.data_dir =
-                               qtcb->bottom.io.data_direction;
-               }
-               break;
-
-       case FSF_QTCB_OPEN_PORT_WITH_DID:
-       case FSF_QTCB_CLOSE_PORT:
-       case FSF_QTCB_CLOSE_PHYSICAL_PORT:
-               port = (struct zfcp_port *)fsf_req->data;
-               response->u.port.wwpn = port->wwpn;
-               response->u.port.d_id = port->d_id;
-               response->u.port.port_handle = qtcb->header.port_handle;
-               break;
-
-       case FSF_QTCB_OPEN_LUN:
-       case FSF_QTCB_CLOSE_LUN:
-               unit = (struct zfcp_unit *)fsf_req->data;
-               port = unit->port;
-               response->u.unit.wwpn = port->wwpn;
-               response->u.unit.fcp_lun = unit->fcp_lun;
-               response->u.unit.port_handle = qtcb->header.port_handle;
-               response->u.unit.lun_handle = qtcb->header.lun_handle;
-               break;
-
-       case FSF_QTCB_SEND_ELS:
-               send_els = (struct zfcp_send_els *)fsf_req->data;
-               response->u.els.d_id = ntoh24(qtcb->bottom.support.d_id);
-               break;
-
-       case FSF_QTCB_ABORT_FCP_CMND:
-       case FSF_QTCB_SEND_GENERIC:
-       case FSF_QTCB_EXCHANGE_CONFIG_DATA:
-       case FSF_QTCB_EXCHANGE_PORT_DATA:
-       case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
-       case FSF_QTCB_UPLOAD_CONTROL_FILE:
-               break;
-       }
-
-       debug_event(dbf->hba, level, rec, sizeof(*rec));
 
-       /* have fcp channel microcode fixed to use as little as possible */
-       if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) {
-               /* adjust length skipping trailing zeros */
-               char *buf = (char *)qtcb + qtcb->header.log_start;
-               int len = qtcb->header.log_length;
-               for (; len && !buf[len - 1]; len--);
-               zfcp_dbf_hexdump(dbf->hba, rec, sizeof(*rec), level, buf,
-                                len);
+       memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+       rec->id = ZFCP_DBF_HBA_RES;
+       rec->fsf_req_id = req->req_id;
+       rec->fsf_req_status = req->status;
+       rec->fsf_cmd = req->fsf_command;
+       rec->fsf_seq_no = req->seq_no;
+       rec->u.res.req_issued = req->issued;
+       rec->u.res.prot_status = q_pref->prot_status;
+       rec->u.res.fsf_status = q_head->fsf_status;
+
+       memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual,
+              FSF_PROT_STATUS_QUAL_SIZE);
+       memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual,
+              FSF_STATUS_QUALIFIER_SIZE);
+
+       if (req->fsf_command != FSF_QTCB_FCP_CMND) {
+               rec->pl_len = q_head->log_length;
+               zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
+                                 rec->pl_len, "fsf_res", req->req_id);
        }
 
-       spin_unlock_irqrestore(&dbf->hba_lock, flags);
-}
-
-void _zfcp_dbf_hba_fsf_unsol(const char *tag, int level, struct zfcp_dbf *dbf,
-                            struct fsf_status_read_buffer *status_buffer)
-{
-       struct zfcp_dbf_hba_record *rec = &dbf->hba_buf;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dbf->hba_lock, flags);
-       memset(rec, 0, sizeof(*rec));
-       strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
-       strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);
-
-       rec->u.status.failed = atomic_read(&dbf->adapter->stat_miss);
-       if (status_buffer != NULL) {
-               rec->u.status.status_type = status_buffer->status_type;
-               rec->u.status.status_subtype = status_buffer->status_subtype;
-               memcpy(&rec->u.status.queue_designator,
-                      &status_buffer->queue_designator,
-                      sizeof(struct fsf_queue_designator));
-
-               switch (status_buffer->status_type) {
-               case FSF_STATUS_READ_SENSE_DATA_AVAIL:
-                       rec->u.status.payload_size =
-                           ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;
-                       break;
-
-               case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
-                       rec->u.status.payload_size =
-                           ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;
-                       break;
-
-               case FSF_STATUS_READ_LINK_DOWN:
-                       switch (status_buffer->status_subtype) {
-                       case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
-                       case FSF_STATUS_READ_SUB_FDISC_FAILED:
-                               rec->u.status.payload_size =
-                                       sizeof(struct fsf_link_down_info);
-                       }
-                       break;
-
-               case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
-                       rec->u.status.payload_size =
-                           ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;
-                       break;
-               }
-               memcpy(&rec->u.status.payload,
-                      &status_buffer->payload, rec->u.status.payload_size);
-       }
-
-       debug_event(dbf->hba, level, rec, sizeof(*rec));
+       debug_event(dbf->hba, 1, rec, sizeof(*rec));
        spin_unlock_irqrestore(&dbf->hba_lock, flags);
 }
 
 /**
- * zfcp_dbf_hba_qdio - trace event for QDIO related failure
- * @qdio: qdio structure affected by this QDIO related event
- * @qdio_error: as passed by qdio module
- * @sbal_index: first buffer with error condition, as passed by qdio module
- * @sbal_count: number of buffers affected, as passed by qdio module
+ * zfcp_dbf_hba_fsf_uss - trace event for an unsolicited status buffer
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @req: request providing the unsolicited status
  */
-void zfcp_dbf_hba_qdio(struct zfcp_dbf *dbf, unsigned int qdio_error,
-                      int sbal_index, int sbal_count)
+void zfcp_dbf_hba_fsf_uss(char *tag, struct zfcp_fsf_req *req)
 {
-       struct zfcp_dbf_hba_record *r = &dbf->hba_buf;
+       struct zfcp_dbf *dbf = req->adapter->dbf;
+       struct fsf_status_read_buffer *srb = req->data;
+       struct zfcp_dbf_hba *rec = &dbf->hba_buf;
        unsigned long flags;
 
        spin_lock_irqsave(&dbf->hba_lock, flags);
-       memset(r, 0, sizeof(*r));
-       strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE);
-       r->u.qdio.qdio_error = qdio_error;
-       r->u.qdio.sbal_index = sbal_index;
-       r->u.qdio.sbal_count = sbal_count;
-       debug_event(dbf->hba, 0, r, sizeof(*r));
+       memset(rec, 0, sizeof(*rec));
+
+       memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+       rec->id = ZFCP_DBF_HBA_USS;
+       rec->fsf_req_id = req->req_id;
+       rec->fsf_req_status = req->status;
+       rec->fsf_cmd = req->fsf_command;
+
+       if (!srb)
+               goto log;
+
+       rec->u.uss.status_type = srb->status_type;
+       rec->u.uss.status_subtype = srb->status_subtype;
+       rec->u.uss.d_id = ntoh24(srb->d_id);
+       rec->u.uss.lun = srb->fcp_lun;
+       memcpy(&rec->u.uss.queue_designator, &srb->queue_designator,
+              sizeof(rec->u.uss.queue_designator));
+
+       /* status read buffer payload length */
+       rec->pl_len = (!srb->length) ? 0 : srb->length -
+                       offsetof(struct fsf_status_read_buffer, payload);
+
+       if (rec->pl_len)
+               zfcp_dbf_pl_write(dbf, srb->payload.data, rec->pl_len,
+                                 "fsf_uss", req->req_id);
+log:
+       debug_event(dbf->hba, 2, rec, sizeof(*rec));
        spin_unlock_irqrestore(&dbf->hba_lock, flags);
 }
 
 /**
- * zfcp_dbf_hba_berr - trace event for bit error threshold
- * @dbf: dbf structure affected by this QDIO related event
- * @req: fsf request
+ * zfcp_dbf_hba_bit_err - trace event for bit error conditions
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @req: request which caused the bit_error condition
  */
-void zfcp_dbf_hba_berr(struct zfcp_dbf *dbf, struct zfcp_fsf_req *req)
+void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req)
 {
-       struct zfcp_dbf_hba_record *r = &dbf->hba_buf;
+       struct zfcp_dbf *dbf = req->adapter->dbf;
+       struct zfcp_dbf_hba *rec = &dbf->hba_buf;
        struct fsf_status_read_buffer *sr_buf = req->data;
-       struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error;
        unsigned long flags;
 
        spin_lock_irqsave(&dbf->hba_lock, flags);
-       memset(r, 0, sizeof(*r));
-       strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE);
-       memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload));
-       debug_event(dbf->hba, 0, r, sizeof(*r));
-       spin_unlock_irqrestore(&dbf->hba_lock, flags);
-}
-static void zfcp_dbf_hba_view_response(char **p,
-                                      struct zfcp_dbf_hba_record_response *r)
-{
-       struct timespec t;
-
-       zfcp_dbf_out(p, "fsf_command", "0x%08x", r->fsf_command);
-       zfcp_dbf_out(p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
-       zfcp_dbf_out(p, "fsf_seqno", "0x%08x", r->fsf_seqno);
-       stck_to_timespec(r->fsf_issued, &t);
-       zfcp_dbf_out(p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
-       zfcp_dbf_out(p, "fsf_prot_status", "0x%08x", r->fsf_prot_status);
-       zfcp_dbf_out(p, "fsf_status", "0x%08x", r->fsf_status);
-       zfcp_dbf_outd(p, "fsf_prot_status_qual", r->fsf_prot_status_qual,
-                     FSF_PROT_STATUS_QUAL_SIZE, 0, FSF_PROT_STATUS_QUAL_SIZE);
-       zfcp_dbf_outd(p, "fsf_status_qual", r->fsf_status_qual,
-                     FSF_STATUS_QUALIFIER_SIZE, 0, FSF_STATUS_QUALIFIER_SIZE);
-       zfcp_dbf_out(p, "fsf_req_status", "0x%08x", r->fsf_req_status);
-       zfcp_dbf_out(p, "sbal_first", "0x%02x", r->sbal_first);
-       zfcp_dbf_out(p, "sbal_last", "0x%02x", r->sbal_last);
-       zfcp_dbf_out(p, "sbal_response", "0x%02x", r->sbal_response);
-       zfcp_dbf_out(p, "pool", "0x%02x", r->pool);
-
-       switch (r->fsf_command) {
-       case FSF_QTCB_FCP_CMND:
-               if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
-                       break;
-               zfcp_dbf_out(p, "data_direction", "0x%04x", r->u.fcp.data_dir);
-               zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
-               *p += sprintf(*p, "\n");
-               break;
-
-       case FSF_QTCB_OPEN_PORT_WITH_DID:
-       case FSF_QTCB_CLOSE_PORT:
-       case FSF_QTCB_CLOSE_PHYSICAL_PORT:
-               zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.port.wwpn);
-               zfcp_dbf_out(p, "d_id", "0x%06x", r->u.port.d_id);
-               zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.port.port_handle);
-               break;
-
-       case FSF_QTCB_OPEN_LUN:
-       case FSF_QTCB_CLOSE_LUN:
-               zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.unit.wwpn);
-               zfcp_dbf_out(p, "fcp_lun", "0x%016Lx", r->u.unit.fcp_lun);
-               zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.unit.port_handle);
-               zfcp_dbf_out(p, "lun_handle", "0x%08x", r->u.unit.lun_handle);
-               break;
-
-       case FSF_QTCB_SEND_ELS:
-               zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id);
-               break;
-
-       case FSF_QTCB_ABORT_FCP_CMND:
-       case FSF_QTCB_SEND_GENERIC:
-       case FSF_QTCB_EXCHANGE_CONFIG_DATA:
-       case FSF_QTCB_EXCHANGE_PORT_DATA:
-       case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
-       case FSF_QTCB_UPLOAD_CONTROL_FILE:
-               break;
-       }
-}
-
-static void zfcp_dbf_hba_view_status(char **p,
-                                    struct zfcp_dbf_hba_record_status *r)
-{
-       zfcp_dbf_out(p, "failed", "0x%02x", r->failed);
-       zfcp_dbf_out(p, "status_type", "0x%08x", r->status_type);
-       zfcp_dbf_out(p, "status_subtype", "0x%08x", r->status_subtype);
-       zfcp_dbf_outd(p, "queue_designator", (char *)&r->queue_designator,
-                     sizeof(struct fsf_queue_designator), 0,
-                     sizeof(struct fsf_queue_designator));
-       zfcp_dbf_outd(p, "payload", (char *)&r->payload, r->payload_size, 0,
-                     r->payload_size);
-}
-
-static void zfcp_dbf_hba_view_qdio(char **p, struct zfcp_dbf_hba_record_qdio *r)
-{
-       zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error);
-       zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index);
-       zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count);
-}
+       memset(rec, 0, sizeof(*rec));
 
-static void zfcp_dbf_hba_view_berr(char **p, struct fsf_bit_error_payload *r)
-{
-       zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count);
-       zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count);
-       zfcp_dbf_out(p, "loss_of_sig_err", "%d", r->loss_of_signal_error_count);
-       zfcp_dbf_out(p, "prim_seq_err", "%d",
-                    r->primitive_sequence_error_count);
-       zfcp_dbf_out(p, "inval_trans_word_err", "%d",
-                    r->invalid_transmission_word_error_count);
-       zfcp_dbf_out(p, "CRC_errors", "%d", r->crc_error_count);
-       zfcp_dbf_out(p, "prim_seq_event_to", "%d",
-                    r->primitive_sequence_event_timeout_count);
-       zfcp_dbf_out(p, "elast_buf_overrun_err", "%d",
-                    r->elastic_buffer_overrun_error_count);
-       zfcp_dbf_out(p, "adv_rec_buf2buf_cred", "%d",
-                    r->advertised_receive_b2b_credit);
-       zfcp_dbf_out(p, "curr_rec_buf2buf_cred", "%d",
-                    r->current_receive_b2b_credit);
-       zfcp_dbf_out(p, "adv_trans_buf2buf_cred", "%d",
-                    r->advertised_transmit_b2b_credit);
-       zfcp_dbf_out(p, "curr_trans_buf2buf_cred", "%d",
-                    r->current_transmit_b2b_credit);
-}
+       memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+       rec->id = ZFCP_DBF_HBA_BIT;
+       rec->fsf_req_id = req->req_id;
+       rec->fsf_req_status = req->status;
+       rec->fsf_cmd = req->fsf_command;
+       memcpy(&rec->u.be, &sr_buf->payload.bit_error,
+              sizeof(struct fsf_bit_error_payload));
 
-static int zfcp_dbf_hba_view_format(debug_info_t *id, struct debug_view *view,
-                                   char *out_buf, const char *in_buf)
-{
-       struct zfcp_dbf_hba_record *r = (struct zfcp_dbf_hba_record *)in_buf;
-       char *p = out_buf;
-
-       if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
-               return 0;
-
-       zfcp_dbf_tag(&p, "tag", r->tag);
-       if (isalpha(r->tag2[0]))
-               zfcp_dbf_tag(&p, "tag2", r->tag2);
-
-       if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
-               zfcp_dbf_hba_view_response(&p, &r->u.response);
-       else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
-               zfcp_dbf_hba_view_status(&p, &r->u.status);
-       else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
-               zfcp_dbf_hba_view_qdio(&p, &r->u.qdio);
-       else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
-               zfcp_dbf_hba_view_berr(&p, &r->u.berr);
-
-       if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0)
-               p += sprintf(p, "\n");
-       return p - out_buf;
+       debug_event(dbf->hba, 1, rec, sizeof(*rec));
+       spin_unlock_irqrestore(&dbf->hba_lock, flags);
 }
 
-static struct debug_view zfcp_dbf_hba_view = {
-       .name = "structured",
-       .header_proc = zfcp_dbf_view_header,
-       .format_proc = zfcp_dbf_hba_view_format,
-};
-
-static const char *zfcp_dbf_rec_tags[] = {
-       [ZFCP_REC_DBF_ID_THREAD] = "thread",
-       [ZFCP_REC_DBF_ID_TARGET] = "target",
-       [ZFCP_REC_DBF_ID_TRIGGER] = "trigger",
-       [ZFCP_REC_DBF_ID_ACTION] = "action",
-};
-
-static int zfcp_dbf_rec_view_format(debug_info_t *id, struct debug_view *view,
-                                   char *buf, const char *_rec)
+static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec,
+                               struct zfcp_adapter *adapter,
+                               struct zfcp_port *port,
+                               struct scsi_device *sdev)
 {
-       struct zfcp_dbf_rec_record *r = (struct zfcp_dbf_rec_record *)_rec;
-       char *p = buf;
-       char hint[ZFCP_DBF_ID_SIZE + 1];
-
-       memcpy(hint, r->id2, ZFCP_DBF_ID_SIZE);
-       hint[ZFCP_DBF_ID_SIZE] = 0;
-       zfcp_dbf_outs(&p, "tag", zfcp_dbf_rec_tags[r->id]);
-       zfcp_dbf_outs(&p, "hint", hint);
-       switch (r->id) {
-       case ZFCP_REC_DBF_ID_THREAD:
-               zfcp_dbf_out(&p, "total", "%d", r->u.thread.total);
-               zfcp_dbf_out(&p, "ready", "%d", r->u.thread.ready);
-               zfcp_dbf_out(&p, "running", "%d", r->u.thread.running);
-               break;
-       case ZFCP_REC_DBF_ID_TARGET:
-               zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.target.ref);
-               zfcp_dbf_out(&p, "status", "0x%08x", r->u.target.status);
-               zfcp_dbf_out(&p, "erp_count", "%d", r->u.target.erp_count);
-               zfcp_dbf_out(&p, "d_id", "0x%06x", r->u.target.d_id);
-               zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.target.wwpn);
-               zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.target.fcp_lun);
-               break;
-       case ZFCP_REC_DBF_ID_TRIGGER:
-               zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.trigger.ref);
-               zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.trigger.action);
-               zfcp_dbf_out(&p, "requested", "%d", r->u.trigger.want);
-               zfcp_dbf_out(&p, "executed", "%d", r->u.trigger.need);
-               zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.trigger.wwpn);
-               zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun);
-               zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as);
-               zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps);
-               zfcp_dbf_out(&p, "lun_status", "0x%08x", r->u.trigger.ls);
-               break;
-       case ZFCP_REC_DBF_ID_ACTION:
-               zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action);
-               zfcp_dbf_out(&p, "fsf_req", "0x%016Lx", r->u.action.fsf_req);
-               zfcp_dbf_out(&p, "status", "0x%08Lx", r->u.action.status);
-               zfcp_dbf_out(&p, "step", "0x%08Lx", r->u.action.step);
-               break;
+       rec->adapter_status = atomic_read(&adapter->status);
+       if (port) {
+               rec->port_status = atomic_read(&port->status);
+               rec->wwpn = port->wwpn;
+               rec->d_id = port->d_id;
+       }
+       if (sdev) {
+               rec->lun_status = atomic_read(&sdev_to_zfcp(sdev)->status);
+               rec->lun = zfcp_scsi_dev_lun(sdev);
        }
-       p += sprintf(p, "\n");
-       return p - buf;
 }
 
-static struct debug_view zfcp_dbf_rec_view = {
-       .name = "structured",
-       .header_proc = zfcp_dbf_view_header,
-       .format_proc = zfcp_dbf_rec_view_format,
-};
-
 /**
- * zfcp_dbf_rec_thread - trace event related to recovery thread operation
- * @id2: identifier for event
- * @dbf: reference to dbf structure
- * This function assumes that the caller is holding erp_lock.
+ * zfcp_dbf_rec_trig - trace event related to triggered recovery
+ * @tag: identifier for event
+ * @adapter: adapter on which the erp_action should run
+ * @port: remote port involved in the erp_action
+ * @sdev: scsi device involved in the erp_action
+ * @want: wanted erp_action
+ * @need: required erp_action
+ *
+ * The adapter->erp_lock has to be held.
  */
-void zfcp_dbf_rec_thread(char *id2, struct zfcp_dbf *dbf)
+void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter,
+                      struct zfcp_port *port, struct scsi_device *sdev,
+                      u8 want, u8 need)
 {
-       struct zfcp_adapter *adapter = dbf->adapter;
-       struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
-       unsigned long flags = 0;
+       struct zfcp_dbf *dbf = adapter->dbf;
+       struct zfcp_dbf_rec *rec = &dbf->rec_buf;
        struct list_head *entry;
-       unsigned ready = 0, running = 0, total;
-
-       list_for_each(entry, &adapter->erp_ready_head)
-               ready++;
-       list_for_each(entry, &adapter->erp_running_head)
-               running++;
-       total = adapter->erp_total_count;
-
-       spin_lock_irqsave(&dbf->rec_lock, flags);
-       memset(r, 0, sizeof(*r));
-       r->id = ZFCP_REC_DBF_ID_THREAD;
-       memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
-       r->u.thread.total = total;
-       r->u.thread.ready = ready;
-       r->u.thread.running = running;
-       debug_event(dbf->rec, 6, r, sizeof(*r));
-       spin_unlock_irqrestore(&dbf->rec_lock, flags);
-}
-
-/**
- * zfcp_dbf_rec_thread - trace event related to recovery thread operation
- * @id2: identifier for event
- * @adapter: adapter
- * This function assumes that the caller does not hold erp_lock.
- */
-void zfcp_dbf_rec_thread_lock(char *id2, struct zfcp_dbf *dbf)
-{
-       struct zfcp_adapter *adapter = dbf->adapter;
-       unsigned long flags;
-
-       read_lock_irqsave(&adapter->erp_lock, flags);
-       zfcp_dbf_rec_thread(id2, dbf);
-       read_unlock_irqrestore(&adapter->erp_lock, flags);
-}
-
-static void zfcp_dbf_rec_target(char *id2, void *ref, struct zfcp_dbf *dbf,
-                               atomic_t *status, atomic_t *erp_count, u64 wwpn,
-                               u32 d_id, u64 fcp_lun)
-{
-       struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
        unsigned long flags;
 
        spin_lock_irqsave(&dbf->rec_lock, flags);
-       memset(r, 0, sizeof(*r));
-       r->id = ZFCP_REC_DBF_ID_TARGET;
-       memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
-       r->u.target.ref = (unsigned long)ref;
-       r->u.target.status = atomic_read(status);
-       r->u.target.wwpn = wwpn;
-       r->u.target.d_id = d_id;
-       r->u.target.fcp_lun = fcp_lun;
-       r->u.target.erp_count = atomic_read(erp_count);
-       debug_event(dbf->rec, 3, r, sizeof(*r));
-       spin_unlock_irqrestore(&dbf->rec_lock, flags);
-}
-
-/**
- * zfcp_dbf_rec_adapter - trace event for adapter state change
- * @id: identifier for trigger of state change
- * @ref: additional reference (e.g. request)
- * @dbf: reference to dbf structure
- */
-void zfcp_dbf_rec_adapter(char *id, void *ref, struct zfcp_dbf *dbf)
-{
-       struct zfcp_adapter *adapter = dbf->adapter;
-
-       zfcp_dbf_rec_target(id, ref, dbf, &adapter->status,
-                           &adapter->erp_counter, 0, 0,
-                           ZFCP_DBF_INVALID_LUN);
-}
-
-/**
- * zfcp_dbf_rec_port - trace event for port state change
- * @id: identifier for trigger of state change
- * @ref: additional reference (e.g. request)
- * @port: port
- */
-void zfcp_dbf_rec_port(char *id, void *ref, struct zfcp_port *port)
-{
-       struct zfcp_dbf *dbf = port->adapter->dbf;
+       memset(rec, 0, sizeof(*rec));
 
-       zfcp_dbf_rec_target(id, ref, dbf, &port->status,
-                           &port->erp_counter, port->wwpn, port->d_id,
-                           ZFCP_DBF_INVALID_LUN);
-}
+       rec->id = ZFCP_DBF_REC_TRIG;
+       memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+       zfcp_dbf_set_common(rec, adapter, port, sdev);
 
-/**
- * zfcp_dbf_rec_lun - trace event for LUN state change
- * @id: identifier for trigger of state change
- * @ref: additional reference (e.g. request)
- * @sdev: SCSI device
- */
-void zfcp_dbf_rec_lun(char *id, void *ref, struct scsi_device *sdev)
-{
-       struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
-       struct zfcp_port *port = zfcp_sdev->port;
-       struct zfcp_dbf *dbf = port->adapter->dbf;
+       list_for_each(entry, &adapter->erp_ready_head)
+               rec->u.trig.ready++;
 
-       zfcp_dbf_rec_target(id, ref, dbf, &zfcp_sdev->status,
-                           &zfcp_sdev->erp_counter, port->wwpn, port->d_id,
-                           zfcp_scsi_dev_lun(sdev));
-}
+       list_for_each(entry, &adapter->erp_running_head)
+               rec->u.trig.running++;
 
-/**
- * zfcp_dbf_rec_trigger - trace event for triggered error recovery
- * @id2: identifier for error recovery trigger
- * @ref: additional reference (e.g. request)
- * @want: originally requested error recovery action
- * @need: error recovery action actually initiated
- * @action: address of error recovery action struct
- * @adapter: adapter
- * @port: port
- * @sdev: SCSI device
- */
-void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action,
-                         struct zfcp_adapter *adapter, struct zfcp_port *port,
-                         struct scsi_device *sdev)
-{
-       struct zfcp_dbf *dbf = adapter->dbf;
-       struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
-       unsigned long flags;
+       rec->u.trig.want = want;
+       rec->u.trig.need = need;
 
-       spin_lock_irqsave(&dbf->rec_lock, flags);
-       memset(r, 0, sizeof(*r));
-       r->id = ZFCP_REC_DBF_ID_TRIGGER;
-       memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
-       r->u.trigger.ref = (unsigned long)ref;
-       r->u.trigger.want = want;
-       r->u.trigger.need = need;
-       r->u.trigger.action = (unsigned long)action;
-       r->u.trigger.as = atomic_read(&adapter->status);
-       if (port) {
-               r->u.trigger.ps = atomic_read(&port->status);
-               r->u.trigger.wwpn = port->wwpn;
-       }
-       if (sdev)
-               r->u.trigger.ls = atomic_read(&sdev_to_zfcp(sdev)->status);
-       r->u.trigger.fcp_lun = sdev ? zfcp_scsi_dev_lun(sdev) :
-                                     ZFCP_DBF_INVALID_LUN;
-       debug_event(dbf->rec, action ? 1 : 4, r, sizeof(*r));
+       debug_event(dbf->rec, 1, rec, sizeof(*rec));
        spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
 
+
 /**
- * zfcp_dbf_rec_action - trace event showing progress of recovery action
- * @id2: identifier
- * @erp_action: error recovery action struct pointer
+ * zfcp_dbf_rec_run - trace event related to running recovery
+ * @tag: identifier for event
+ * @erp: erp_action running
  */
-void zfcp_dbf_rec_action(char *id2, struct zfcp_erp_action *erp_action)
+void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
 {
-       struct zfcp_dbf *dbf = erp_action->adapter->dbf;
-       struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
+       struct zfcp_dbf *dbf = erp->adapter->dbf;
+       struct zfcp_dbf_rec *rec = &dbf->rec_buf;
        unsigned long flags;
 
        spin_lock_irqsave(&dbf->rec_lock, flags);
-       memset(r, 0, sizeof(*r));
-       r->id = ZFCP_REC_DBF_ID_ACTION;
-       memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
-       r->u.action.action = (unsigned long)erp_action;
-       r->u.action.status = erp_action->status;
-       r->u.action.step = erp_action->step;
-       r->u.action.fsf_req = erp_action->fsf_req_id;
-       debug_event(dbf->rec, 5, r, sizeof(*r));
-       spin_unlock_irqrestore(&dbf->rec_lock, flags);
-}
+       memset(rec, 0, sizeof(*rec));
 
-/**
- * zfcp_dbf_san_ct_request - trace event for issued CT request
- * @fsf_req: request containing issued CT data
- * @d_id: destination id where ct request is sent to
- */
-void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req, u32 d_id)
-{
-       struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
-       struct zfcp_adapter *adapter = fsf_req->adapter;
-       struct zfcp_dbf *dbf = adapter->dbf;
-       struct fc_ct_hdr *hdr = sg_virt(ct->req);
-       struct zfcp_dbf_san_record *r = &dbf->san_buf;
-       struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req;
-       int level = 3;
-       unsigned long flags;
+       rec->id = ZFCP_DBF_REC_RUN;
+       memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+       zfcp_dbf_set_common(rec, erp->adapter, erp->port, erp->sdev);
 
-       spin_lock_irqsave(&dbf->san_lock, flags);
-       memset(r, 0, sizeof(*r));
-       strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE);
-       r->fsf_reqid = fsf_req->req_id;
-       r->fsf_seqno = fsf_req->seq_no;
-       oct->d_id = d_id;
-       oct->cmd_req_code = hdr->ct_cmd;
-       oct->revision = hdr->ct_rev;
-       oct->gs_type = hdr->ct_fs_type;
-       oct->gs_subtype = hdr->ct_fs_subtype;
-       oct->options = hdr->ct_options;
-       oct->max_res_size = hdr->ct_mr_size;
-       oct->len = min((int)ct->req->length - (int)sizeof(struct fc_ct_hdr),
-                      ZFCP_DBF_SAN_MAX_PAYLOAD);
-       debug_event(dbf->san, level, r, sizeof(*r));
-       zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
-                        (void *)hdr + sizeof(struct fc_ct_hdr), oct->len);
-       spin_unlock_irqrestore(&dbf->san_lock, flags);
-}
+       rec->u.run.fsf_req_id = erp->fsf_req_id;
+       rec->u.run.rec_status = erp->status;
+       rec->u.run.rec_step = erp->step;
+       rec->u.run.rec_action = erp->action;
 
-/**
- * zfcp_dbf_san_ct_response - trace event for completion of CT request
- * @fsf_req: request containing CT response
- */
-void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req)
-{
-       struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
-       struct zfcp_adapter *adapter = fsf_req->adapter;
-       struct fc_ct_hdr *hdr = sg_virt(ct->resp);
-       struct zfcp_dbf *dbf = adapter->dbf;
-       struct zfcp_dbf_san_record *r = &dbf->san_buf;
-       struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp;
-       int level = 3;
-       unsigned long flags;
+       if (erp->sdev)
+               rec->u.run.rec_count =
+                       atomic_read(&sdev_to_zfcp(erp->sdev)->erp_counter);
+       else if (erp->port)
+               rec->u.run.rec_count = atomic_read(&erp->port->erp_counter);
+       else
+               rec->u.run.rec_count = atomic_read(&erp->adapter->erp_counter);
 
-       spin_lock_irqsave(&dbf->san_lock, flags);
-       memset(r, 0, sizeof(*r));
-       strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
-       r->fsf_reqid = fsf_req->req_id;
-       r->fsf_seqno = fsf_req->seq_no;
-       rct->cmd_rsp_code = hdr->ct_cmd;
-       rct->revision = hdr->ct_rev;
-       rct->reason_code = hdr->ct_reason;
-       rct->expl = hdr->ct_explan;
-       rct->vendor_unique = hdr->ct_vendor;
-       rct->max_res_size = hdr->ct_mr_size;
-       rct->len = min((int)ct->resp->length - (int)sizeof(struct fc_ct_hdr),
-                      ZFCP_DBF_SAN_MAX_PAYLOAD);
-       debug_event(dbf->san, level, r, sizeof(*r));
-       zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
-                        (void *)hdr + sizeof(struct fc_ct_hdr), rct->len);
-       spin_unlock_irqrestore(&dbf->san_lock, flags);
+       debug_event(dbf->rec, 1, rec, sizeof(*rec));
+       spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
 
-static void zfcp_dbf_san_els(const char *tag, int level,
-                            struct zfcp_fsf_req *fsf_req, u32 d_id,
-                            void *buffer, int buflen)
+static inline
+void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
+                 u64 req_id, u32 d_id)
 {
-       struct zfcp_adapter *adapter = fsf_req->adapter;
-       struct zfcp_dbf *dbf = adapter->dbf;
-       struct zfcp_dbf_san_record *rec = &dbf->san_buf;
+       struct zfcp_dbf_san *rec = &dbf->san_buf;
+       u16 rec_len;
        unsigned long flags;
 
        spin_lock_irqsave(&dbf->san_lock, flags);
        memset(rec, 0, sizeof(*rec));
-       strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
-       rec->fsf_reqid = fsf_req->req_id;
-       rec->fsf_seqno = fsf_req->seq_no;
-       rec->u.els.d_id = d_id;
-       debug_event(dbf->san, level, rec, sizeof(*rec));
-       zfcp_dbf_hexdump(dbf->san, rec, sizeof(*rec), level,
-                        buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
+
+       rec->id = id;
+       rec->fsf_req_id = req_id;
+       rec->d_id = d_id;
+       rec_len = min(len, (u16)ZFCP_DBF_SAN_MAX_PAYLOAD);
+       memcpy(rec->payload, data, rec_len);
+       memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+
+       debug_event(dbf->san, 1, rec, sizeof(*rec));
        spin_unlock_irqrestore(&dbf->san_lock, flags);
 }
 
 /**
- * zfcp_dbf_san_els_request - trace event for issued ELS
- * @fsf_req: request containing issued ELS
+ * zfcp_dbf_san_req - trace event for issued SAN request
+ * @tag: indentifier for event
+ * @fsf_req: request containing issued CT data
+ * d_id: destination ID
  */
-void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id)
 {
-       struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
-       u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
+       struct zfcp_dbf *dbf = fsf->adapter->dbf;
+       struct zfcp_fsf_ct_els *ct_els = fsf->data;
+       u16 length;
 
-       zfcp_dbf_san_els("oels", 2, fsf_req, d_id,
-                        sg_virt(els->req), els->req->length);
+       length = (u16)(ct_els->req->length + FC_CT_HDR_LEN);
+       zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length,
+                    fsf->req_id, d_id);
 }
 
 /**
- * zfcp_dbf_san_els_response - trace event for completed ELS
- * @fsf_req: request containing ELS response
+ * zfcp_dbf_san_res - trace event for received SAN request
+ * @tag: indentifier for event
+ * @fsf_req: request containing issued CT data
  */
-void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
 {
-       struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
-       u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
+       struct zfcp_dbf *dbf = fsf->adapter->dbf;
+       struct zfcp_fsf_ct_els *ct_els = fsf->data;
+       u16 length;
 
-       zfcp_dbf_san_els("rels", 2, fsf_req, d_id,
-                              sg_virt(els->resp), els->resp->length);
+       length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN);
+       zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
+                    fsf->req_id, 0);
 }
 
 /**
- * zfcp_dbf_san_incoming_els - trace event for incomig ELS
- * @fsf_req: request containing unsolicited status buffer with incoming ELS
+ * zfcp_dbf_san_in_els - trace event for incoming ELS
+ * @tag: indentifier for event
+ * @fsf_req: request containing issued CT data
  */
-void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
 {
-       struct fsf_status_read_buffer *buf =
-                       (struct fsf_status_read_buffer *)fsf_req->data;
-       int length = (int)buf->length -
-                    (int)((void *)&buf->payload - (void *)buf);
+       struct zfcp_dbf *dbf = fsf->adapter->dbf;
+       struct fsf_status_read_buffer *srb =
+               (struct fsf_status_read_buffer *) fsf->data;
+       u16 length;
 
-       zfcp_dbf_san_els("iels", 1, fsf_req, ntoh24(buf->d_id),
-                              (void *)buf->payload.data, length);
-}
-
-static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
-                                   char *out_buf, const char *in_buf)
-{
-       struct zfcp_dbf_san_record *r = (struct zfcp_dbf_san_record *)in_buf;
-       char *p = out_buf;
-
-       if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
-               return 0;
-
-       zfcp_dbf_tag(&p, "tag", r->tag);
-       zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
-       zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
-
-       if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
-               struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req;
-               zfcp_dbf_out(&p, "d_id", "0x%06x", ct->d_id);
-               zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code);
-               zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
-               zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type);
-               zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype);
-               zfcp_dbf_out(&p, "options", "0x%02x", ct->options);
-               zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
-       } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
-               struct zfcp_dbf_san_record_ct_response *ct = &r->u.ct_resp;
-               zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code);
-               zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
-               zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code);
-               zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl);
-               zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique);
-               zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
-       } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
-                  strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
-                  strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
-               struct zfcp_dbf_san_record_els *els = &r->u.els;
-               zfcp_dbf_out(&p, "d_id", "0x%06x", els->d_id);
-       }
-       return p - out_buf;
+       length = (u16)(srb->length -
+                       offsetof(struct fsf_status_read_buffer, payload));
+       zfcp_dbf_san(tag, dbf, srb->payload.data, ZFCP_DBF_SAN_ELS, length,
+                    fsf->req_id, ntoh24(srb->d_id));
 }
 
-static struct debug_view zfcp_dbf_san_view = {
-       .name = "structured",
-       .header_proc = zfcp_dbf_view_header,
-       .format_proc = zfcp_dbf_san_view_format,
-};
-
-void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
-                   struct zfcp_dbf *dbf, struct scsi_cmnd *scsi_cmnd,
-                   struct zfcp_fsf_req *fsf_req, unsigned long old_req_id)
+/**
+ * zfcp_dbf_scsi - trace event for scsi commands
+ * @tag: identifier for event
+ * @sc: pointer to struct scsi_cmnd
+ * @fsf: pointer to struct zfcp_fsf_req
+ */
+void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
 {
-       struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf;
-       struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
-       unsigned long flags;
+       struct zfcp_adapter *adapter =
+               (struct zfcp_adapter *) sc->device->host->hostdata[0];
+       struct zfcp_dbf *dbf = adapter->dbf;
+       struct zfcp_dbf_scsi *rec = &dbf->scsi_buf;
        struct fcp_resp_with_ext *fcp_rsp;
-       struct fcp_resp_rsp_info *fcp_rsp_info = NULL;
-       char *fcp_sns_info = NULL;
-       int offset = 0, buflen = 0;
+       struct fcp_resp_rsp_info *fcp_rsp_info;
+       unsigned long flags;
 
        spin_lock_irqsave(&dbf->scsi_lock, flags);
-       do {
-               memset(rec, 0, sizeof(*rec));
-               if (offset == 0) {
-                       strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
-                       strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
-                       if (scsi_cmnd != NULL) {
-                               if (scsi_cmnd->device) {
-                                       rec->scsi_id = scsi_cmnd->device->id;
-                                       rec->scsi_lun = scsi_cmnd->device->lun;
-                               }
-                               rec->scsi_result = scsi_cmnd->result;
-                               rec->scsi_cmnd = (unsigned long)scsi_cmnd;
-                               memcpy(rec->scsi_opcode, scsi_cmnd->cmnd,
-                                       min((int)scsi_cmnd->cmd_len,
-                                               ZFCP_DBF_SCSI_OPCODE));
-                               rec->scsi_retries = scsi_cmnd->retries;
-                               rec->scsi_allowed = scsi_cmnd->allowed;
-                       }
-                       if (fsf_req != NULL) {
-                               fcp_rsp = (struct fcp_resp_with_ext *)
-                                       &(fsf_req->qtcb->bottom.io.fcp_rsp);
-                               fcp_rsp_info = (struct fcp_resp_rsp_info *)
-                                       &fcp_rsp[1];
-                               fcp_sns_info = (char *) &fcp_rsp[1];
-                               if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
-                                       fcp_sns_info += fcp_rsp->ext.fr_sns_len;
-
-                               rec->rsp_validity = fcp_rsp->resp.fr_flags;
-                               rec->rsp_scsi_status = fcp_rsp->resp.fr_status;
-                               rec->rsp_resid = fcp_rsp->ext.fr_resid;
-                               if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
-                                       rec->rsp_code = fcp_rsp_info->rsp_code;
-                               if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
-                                       buflen = min(fcp_rsp->ext.fr_sns_len,
-                                          (u32)ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
-                                       rec->sns_info_len = buflen;
-                                       memcpy(rec->sns_info, fcp_sns_info,
-                                              min(buflen,
-                                                  ZFCP_DBF_SCSI_FCP_SNS_INFO));
-                                       offset += min(buflen,
-                                                     ZFCP_DBF_SCSI_FCP_SNS_INFO);
-                               }
-
-                               rec->fsf_reqid = fsf_req->req_id;
-                               rec->fsf_seqno = fsf_req->seq_no;
-                               rec->fsf_issued = fsf_req->issued;
-                       }
-                       rec->old_fsf_reqid = old_req_id;
-               } else {
-                       strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
-                       dump->total_size = buflen;
-                       dump->offset = offset;
-                       dump->size = min(buflen - offset,
-                                        (int)sizeof(struct
-                                                    zfcp_dbf_scsi_record) -
-                                        (int)sizeof(struct zfcp_dbf_dump));
-                       memcpy(dump->data, fcp_sns_info + offset, dump->size);
-                       offset += dump->size;
-               }
-               debug_event(dbf->scsi, level, rec, sizeof(*rec));
-       } while (offset < buflen);
-       spin_unlock_irqrestore(&dbf->scsi_lock, flags);
-}
+       memset(rec, 0, sizeof(*rec));
 
-static int zfcp_dbf_scsi_view_format(debug_info_t *id, struct debug_view *view,
-                                    char *out_buf, const char *in_buf)
-{
-       struct zfcp_dbf_scsi_record *r = (struct zfcp_dbf_scsi_record *)in_buf;
-       struct timespec t;
-       char *p = out_buf;
-
-       if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
-               return 0;
-
-       zfcp_dbf_tag(&p, "tag", r->tag);
-       zfcp_dbf_tag(&p, "tag2", r->tag2);
-       zfcp_dbf_out(&p, "scsi_id", "0x%08x", r->scsi_id);
-       zfcp_dbf_out(&p, "scsi_lun", "0x%08x", r->scsi_lun);
-       zfcp_dbf_out(&p, "scsi_result", "0x%08x", r->scsi_result);
-       zfcp_dbf_out(&p, "scsi_cmnd", "0x%0Lx", r->scsi_cmnd);
-       zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE,
-                     0, ZFCP_DBF_SCSI_OPCODE);
-       zfcp_dbf_out(&p, "scsi_retries", "0x%02x", r->scsi_retries);
-       zfcp_dbf_out(&p, "scsi_allowed", "0x%02x", r->scsi_allowed);
-       if (strncmp(r->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0)
-               zfcp_dbf_out(&p, "old_fsf_reqid", "0x%0Lx", r->old_fsf_reqid);
-       zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
-       zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
-       stck_to_timespec(r->fsf_issued, &t);
-       zfcp_dbf_out(&p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
-
-       if (strncmp(r->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
-               zfcp_dbf_out(&p, "fcp_rsp_validity", "0x%02x", r->rsp_validity);
-               zfcp_dbf_out(&p, "fcp_rsp_scsi_status", "0x%02x",
-                            r->rsp_scsi_status);
-               zfcp_dbf_out(&p, "fcp_rsp_resid", "0x%08x", r->rsp_resid);
-               zfcp_dbf_out(&p, "fcp_rsp_code", "0x%08x", r->rsp_code);
-               zfcp_dbf_out(&p, "fcp_sns_info_len", "0x%08x", r->sns_info_len);
-               zfcp_dbf_outd(&p, "fcp_sns_info", r->sns_info,
-                             min((int)r->sns_info_len,
-                             ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
-                             r->sns_info_len);
+       memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+       rec->id = ZFCP_DBF_SCSI_CMND;
+       rec->scsi_result = sc->result;
+       rec->scsi_retries = sc->retries;
+       rec->scsi_allowed = sc->allowed;
+       rec->scsi_id = sc->device->id;
+       rec->scsi_lun = sc->device->lun;
+       rec->host_scribble = (unsigned long)sc->host_scribble;
+
+       memcpy(rec->scsi_opcode, sc->cmnd,
+              min((int)sc->cmd_len, ZFCP_DBF_SCSI_OPCODE));
+
+       if (fsf) {
+               rec->fsf_req_id = fsf->req_id;
+               fcp_rsp = (struct fcp_resp_with_ext *)
+                               &(fsf->qtcb->bottom.io.fcp_rsp);
+               memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT);
+               if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) {
+                       fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
+                       rec->fcp_rsp_info = fcp_rsp_info->rsp_code;
+               }
+               if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
+                       rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE,
+                                         (u16)ZFCP_DBF_PAY_MAX_REC);
+                       zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len,
+                                         "fcp_sns", fsf->req_id);
+               }
        }
-       p += sprintf(p, "\n");
-       return p - out_buf;
-}
 
-static struct debug_view zfcp_dbf_scsi_view = {
-       .name = "structured",
-       .header_proc = zfcp_dbf_view_header,
-       .format_proc = zfcp_dbf_scsi_view_format,
-};
+       debug_event(dbf->scsi, 1, rec, sizeof(*rec));
+       spin_unlock_irqrestore(&dbf->scsi_lock, flags);
+}
 
-static debug_info_t *zfcp_dbf_reg(const char *name, int level,
-                                 struct debug_view *view, int size)
+static debug_info_t *zfcp_dbf_reg(const char *name, int size, int rec_size)
 {
        struct debug_info *d;
 
-       d = debug_register(name, dbfsize, level, size);
+       d = debug_register(name, size, 1, rec_size);
        if (!d)
                return NULL;
 
        debug_register_view(d, &debug_hex_ascii_view);
-       debug_register_view(d, view);
-       debug_set_level(d, level);
+       debug_set_level(d, 3);
 
        return d;
 }
 
+static void zfcp_dbf_unregister(struct zfcp_dbf *dbf)
+{
+       if (!dbf)
+               return;
+
+       debug_unregister(dbf->scsi);
+       debug_unregister(dbf->san);
+       debug_unregister(dbf->hba);
+       debug_unregister(dbf->pay);
+       debug_unregister(dbf->rec);
+       kfree(dbf);
+}
+
 /**
  * zfcp_adapter_debug_register - registers debug feature for an adapter
  * @adapter: pointer to adapter for which debug features should be registered
@@ -1003,69 +415,66 @@ static debug_info_t *zfcp_dbf_reg(const char *name, int level,
  */
 int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter)
 {
-       char dbf_name[DEBUG_MAX_NAME_LEN];
+       char name[DEBUG_MAX_NAME_LEN];
        struct zfcp_dbf *dbf;
 
        dbf = kzalloc(sizeof(struct zfcp_dbf), GFP_KERNEL);
        if (!dbf)
                return -ENOMEM;
 
-       dbf->adapter = adapter;
-
+       spin_lock_init(&dbf->pay_lock);
        spin_lock_init(&dbf->hba_lock);
        spin_lock_init(&dbf->san_lock);
        spin_lock_init(&dbf->scsi_lock);
        spin_lock_init(&dbf->rec_lock);
 
        /* debug feature area which records recovery activity */
-       sprintf(dbf_name, "zfcp_%s_rec", dev_name(&adapter->ccw_device->dev));
-       dbf->rec = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_rec_view,
-                               sizeof(struct zfcp_dbf_rec_record));
+       sprintf(name, "zfcp_%s_rec", dev_name(&adapter->ccw_device->dev));
+       dbf->rec = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_rec));
        if (!dbf->rec)
                goto err_out;
 
        /* debug feature area which records HBA (FSF and QDIO) conditions */
-       sprintf(dbf_name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev));
-       dbf->hba = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_hba_view,
-                               sizeof(struct zfcp_dbf_hba_record));
+       sprintf(name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev));
+       dbf->hba = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_hba));
        if (!dbf->hba)
                goto err_out;
 
+       /* debug feature area which records payload info */
+       sprintf(name, "zfcp_%s_pay", dev_name(&adapter->ccw_device->dev));
+       dbf->pay = zfcp_dbf_reg(name, dbfsize * 2, sizeof(struct zfcp_dbf_pay));
+       if (!dbf->pay)
+               goto err_out;
+
        /* debug feature area which records SAN command failures and recovery */
-       sprintf(dbf_name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev));
-       dbf->san = zfcp_dbf_reg(dbf_name, 6, &zfcp_dbf_san_view,
-                               sizeof(struct zfcp_dbf_san_record));
+       sprintf(name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev));
+       dbf->san = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_san));
        if (!dbf->san)
                goto err_out;
 
        /* debug feature area which records SCSI command failures and recovery */
-       sprintf(dbf_name, "zfcp_%s_scsi", dev_name(&adapter->ccw_device->dev));
-       dbf->scsi = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_scsi_view,
-                                sizeof(struct zfcp_dbf_scsi_record));
+       sprintf(name, "zfcp_%s_scsi", dev_name(&adapter->ccw_device->dev));
+       dbf->scsi = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_scsi));
        if (!dbf->scsi)
                goto err_out;
 
        adapter->dbf = dbf;
-       return 0;
 
+       return 0;
 err_out:
-       zfcp_dbf_adapter_unregister(dbf);
+       zfcp_dbf_unregister(dbf);
        return -ENOMEM;
 }
 
 /**
  * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
- * @dbf: pointer to dbf for which debug features should be unregistered
+ * @adapter: pointer to adapter for which debug features should be unregistered
  */
-void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
+void zfcp_dbf_adapter_unregister(struct zfcp_adapter *adapter)
 {
-       if (!dbf)
-               return;
-       debug_unregister(dbf->scsi);
-       debug_unregister(dbf->san);
-       debug_unregister(dbf->hba);
-       debug_unregister(dbf->rec);
-       dbf->adapter->dbf = NULL;
-       kfree(dbf);
+       struct zfcp_dbf *dbf = adapter->dbf;
+
+       adapter->dbf = NULL;
+       zfcp_dbf_unregister(dbf);
 }
 
index 04081b1b62b4b1568ecad4fa0c05b0e917f36bb6..714f087eb7a96bdf973b43665636d14df9adc7a9 100644 (file)
@@ -1,22 +1,8 @@
 /*
- * This file is part of the zfcp device driver for
- * FCP adapters for IBM System z9 and zSeries.
+ * zfcp device driver
+ * debug feature declarations
  *
- * Copyright IBM Corp. 2008, 2009
- *
- * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Copyright IBM Corp. 2008, 2010
  */
 
 #ifndef ZFCP_DBF_H
 #include "zfcp_fsf.h"
 #include "zfcp_def.h"
 
-#define ZFCP_DBF_TAG_SIZE      4
-#define ZFCP_DBF_ID_SIZE       7
+#define ZFCP_DBF_TAG_LEN       7
 
 #define ZFCP_DBF_INVALID_LUN   0xFFFFFFFFFFFFFFFFull
 
-struct zfcp_dbf_dump {
-       u8 tag[ZFCP_DBF_TAG_SIZE];
-       u32 total_size;         /* size of total dump data */
-       u32 offset;             /* how much data has being already dumped */
-       u32 size;               /* how much data comes with this record */
-       u8 data[];              /* dump data */
-} __attribute__ ((packed));
-
-struct zfcp_dbf_rec_record_thread {
-       u32 total;
+/**
+ * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action
+ * @ready: number of ready recovery actions
+ * @running: number of running recovery actions
+ * @want: wanted recovery action
+ * @need: needed recovery action
+ */
+struct zfcp_dbf_rec_trigger {
        u32 ready;
        u32 running;
-};
-
-struct zfcp_dbf_rec_record_target {
-       u64 ref;
-       u32 status;
-       u32 d_id;
-       u64 wwpn;
-       u64 fcp_lun;
-       u32 erp_count;
-};
-
-struct zfcp_dbf_rec_record_trigger {
        u8 want;
        u8 need;
-       u32 as;
-       u32 ps;
-       u32 ls;
-       u64 ref;
-       u64 action;
-       u64 wwpn;
-       u64 fcp_lun;
-};
+} __packed;
 
-struct zfcp_dbf_rec_record_action {
-       u32 status;
-       u32 step;
-       u64 action;
-       u64 fsf_req;
+/**
+ * struct zfcp_dbf_rec_running - trace record for running recovery
+ * @fsf_req_id: request id for fsf requests
+ * @rec_status: status of the fsf request
+ * @rec_step: current step of the recovery action
+ * rec_count: recovery counter
+ */
+struct zfcp_dbf_rec_running {
+       u64 fsf_req_id;
+       u32 rec_status;
+       u16 rec_step;
+       u8 rec_action;
+       u8 rec_count;
+} __packed;
+
+/**
+ * enum zfcp_dbf_rec_id - recovery trace record id
+ * @ZFCP_DBF_REC_TRIG: triggered recovery identifier
+ * @ZFCP_DBF_REC_RUN: running recovery identifier
+ */
+enum zfcp_dbf_rec_id {
+       ZFCP_DBF_REC_TRIG       = 1,
+       ZFCP_DBF_REC_RUN        = 2,
 };
 
-struct zfcp_dbf_rec_record {
+/**
+ * struct zfcp_dbf_rec - trace record for error recovery actions
+ * @id: unique number of recovery record type
+ * @tag: identifier string specifying the location of initiation
+ * @lun: logical unit number
+ * @wwpn: word wide port number
+ * @d_id: destination ID
+ * @adapter_status: current status of the adapter
+ * @port_status: current status of the port
+ * @lun_status: current status of the lun
+ * @u.trig: structure zfcp_dbf_rec_trigger
+ * @u.run: structure zfcp_dbf_rec_running
+ */
+struct zfcp_dbf_rec {
        u8 id;
-       char id2[7];
+       char tag[ZFCP_DBF_TAG_LEN];
+       u64 lun;
+       u64 wwpn;
+       u32 d_id;
+       u32 adapter_status;
+       u32 port_status;
+       u32 lun_status;
        union {
-               struct zfcp_dbf_rec_record_action action;
-               struct zfcp_dbf_rec_record_thread thread;
-               struct zfcp_dbf_rec_record_target target;
-               struct zfcp_dbf_rec_record_trigger trigger;
+               struct zfcp_dbf_rec_trigger trig;
+               struct zfcp_dbf_rec_running run;
        } u;
-};
+} __packed;
 
-enum {
-       ZFCP_REC_DBF_ID_ACTION,
-       ZFCP_REC_DBF_ID_THREAD,
-       ZFCP_REC_DBF_ID_TARGET,
-       ZFCP_REC_DBF_ID_TRIGGER,
+/**
+ * enum zfcp_dbf_san_id - SAN trace record identifier
+ * @ZFCP_DBF_SAN_REQ: request trace record id
+ * @ZFCP_DBF_SAN_RES: response trace record id
+ * @ZFCP_DBF_SAN_ELS: extended link service record id
+ */
+enum zfcp_dbf_san_id {
+       ZFCP_DBF_SAN_REQ        = 1,
+       ZFCP_DBF_SAN_RES        = 2,
+       ZFCP_DBF_SAN_ELS        = 3,
 };
 
-struct zfcp_dbf_hba_record_response {
-       u32 fsf_command;
-       u64 fsf_reqid;
-       u32 fsf_seqno;
-       u64 fsf_issued;
-       u32 fsf_prot_status;
+/** struct zfcp_dbf_san - trace record for SAN requests and responses
+ * @id: unique number of recovery record type
+ * @tag: identifier string specifying the location of initiation
+ * @fsf_req_id: request id for fsf requests
+ * @payload: unformatted information related to request/response
+ * @d_id: destination id
+ */
+struct zfcp_dbf_san {
+       u8 id;
+       char tag[ZFCP_DBF_TAG_LEN];
+       u64 fsf_req_id;
+       u32 d_id;
+#define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32)
+       char payload[ZFCP_DBF_SAN_MAX_PAYLOAD];
+} __packed;
+
+/**
+ * struct zfcp_dbf_hba_res - trace record for hba responses
+ * @req_issued: timestamp when request was issued
+ * @prot_status: protocol status
+ * @prot_status_qual: protocol status qualifier
+ * @fsf_status: fsf status
+ * @fsf_status_qual: fsf status qualifier
+ */
+struct zfcp_dbf_hba_res {
+       u64 req_issued;
+       u32 prot_status;
+       u8  prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
        u32 fsf_status;
-       u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
-       u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
-       u32 fsf_req_status;
-       u8 sbal_first;
-       u8 sbal_last;
-       u8 sbal_response;
-       u8 pool;
-       u64 erp_action;
-       union {
-               struct {
-                       u64 cmnd;
-                       u32 data_dir;
-               } fcp;
-               struct {
-                       u64 wwpn;
-                       u32 d_id;
-                       u32 port_handle;
-               } port;
-               struct {
-                       u64 wwpn;
-                       u64 fcp_lun;
-                       u32 port_handle;
-                       u32 lun_handle;
-               } unit;
-               struct {
-                       u32 d_id;
-               } els;
-       } u;
-} __attribute__ ((packed));
+       u8  fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
+} __packed;
 
-struct zfcp_dbf_hba_record_status {
-       u8 failed;
+/**
+ * struct zfcp_dbf_hba_uss - trace record for unsolicited status
+ * @status_type: type of unsolicited status
+ * @status_subtype: subtype of unsolicited status
+ * @d_id: destination ID
+ * @lun: logical unit number
+ * @queue_designator: queue designator
+ */
+struct zfcp_dbf_hba_uss {
        u32 status_type;
        u32 status_subtype;
-       struct fsf_queue_designator
-        queue_designator;
-       u32 payload_size;
-#define ZFCP_DBF_UNSOL_PAYLOAD                         80
-#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL                32
-#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD     56
-#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT    2 * sizeof(u32)
-       u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
-} __attribute__ ((packed));
-
-struct zfcp_dbf_hba_record_qdio {
-       u32 qdio_error;
-       u8 sbal_index;
-       u8 sbal_count;
-} __attribute__ ((packed));
-
-struct zfcp_dbf_hba_record {
-       u8 tag[ZFCP_DBF_TAG_SIZE];
-       u8 tag2[ZFCP_DBF_TAG_SIZE];
-       union {
-               struct zfcp_dbf_hba_record_response response;
-               struct zfcp_dbf_hba_record_status status;
-               struct zfcp_dbf_hba_record_qdio qdio;
-               struct fsf_bit_error_payload berr;
-       } u;
-} __attribute__ ((packed));
-
-struct zfcp_dbf_san_record_ct_request {
-       u16 cmd_req_code;
-       u8 revision;
-       u8 gs_type;
-       u8 gs_subtype;
-       u8 options;
-       u16 max_res_size;
-       u32 len;
-       u32 d_id;
-} __attribute__ ((packed));
-
-struct zfcp_dbf_san_record_ct_response {
-       u16 cmd_rsp_code;
-       u8 revision;
-       u8 reason_code;
-       u8 expl;
-       u8 vendor_unique;
-       u16 max_res_size;
-       u32 len;
-} __attribute__ ((packed));
-
-struct zfcp_dbf_san_record_els {
        u32 d_id;
-} __attribute__ ((packed));
+       u64 lun;
+       u64 queue_designator;
+} __packed;
 
-struct zfcp_dbf_san_record {
-       u8 tag[ZFCP_DBF_TAG_SIZE];
-       u64 fsf_reqid;
-       u32 fsf_seqno;
+/**
+ * enum zfcp_dbf_hba_id - HBA trace record identifier
+ * @ZFCP_DBF_HBA_RES: response trace record
+ * @ZFCP_DBF_HBA_USS: unsolicited status trace record
+ * @ZFCP_DBF_HBA_BIT: bit error trace record
+ */
+enum zfcp_dbf_hba_id {
+       ZFCP_DBF_HBA_RES        = 1,
+       ZFCP_DBF_HBA_USS        = 2,
+       ZFCP_DBF_HBA_BIT        = 3,
+};
+
+/**
+ * struct zfcp_dbf_hba - common trace record for HBA records
+ * @id: unique number of recovery record type
+ * @tag: identifier string specifying the location of initiation
+ * @fsf_req_id: request id for fsf requests
+ * @fsf_req_status: status of fsf request
+ * @fsf_cmd: fsf command
+ * @fsf_seq_no: fsf sequence number
+ * @pl_len: length of payload stored as zfcp_dbf_pay
+ * @u: record type specific data
+ */
+struct zfcp_dbf_hba {
+       u8 id;
+       char tag[ZFCP_DBF_TAG_LEN];
+       u64 fsf_req_id;
+       u32 fsf_req_status;
+       u32 fsf_cmd;
+       u32 fsf_seq_no;
+       u16 pl_len;
        union {
-               struct zfcp_dbf_san_record_ct_request ct_req;
-               struct zfcp_dbf_san_record_ct_response ct_resp;
-               struct zfcp_dbf_san_record_els els;
+               struct zfcp_dbf_hba_res res;
+               struct zfcp_dbf_hba_uss uss;
+               struct fsf_bit_error_payload be;
        } u;
-} __attribute__ ((packed));
+} __packed;
 
-#define ZFCP_DBF_SAN_MAX_PAYLOAD 1024
+/**
+ * enum zfcp_dbf_scsi_id - scsi trace record identifier
+ * @ZFCP_DBF_SCSI_CMND: scsi command trace record
+ */
+enum zfcp_dbf_scsi_id {
+       ZFCP_DBF_SCSI_CMND      = 1,
+};
 
-struct zfcp_dbf_scsi_record {
-       u8 tag[ZFCP_DBF_TAG_SIZE];
-       u8 tag2[ZFCP_DBF_TAG_SIZE];
+/**
+ * struct zfcp_dbf_scsi - common trace record for SCSI records
+ * @id: unique number of recovery record type
+ * @tag: identifier string specifying the location of initiation
+ * @scsi_id: scsi device id
+ * @scsi_lun: scsi device logical unit number
+ * @scsi_result: scsi result
+ * @scsi_retries: current retry number of scsi request
+ * @scsi_allowed: allowed retries
+ * @fcp_rsp_info: FCP response info
+ * @scsi_opcode: scsi opcode
+ * @fsf_req_id: request id of fsf request
+ * @host_scribble: LLD specific data attached to SCSI request
+ * @pl_len: length of paload stored as zfcp_dbf_pay
+ * @fsf_rsp: response for fsf request
+ */
+struct zfcp_dbf_scsi {
+       u8 id;
+       char tag[ZFCP_DBF_TAG_LEN];
        u32 scsi_id;
        u32 scsi_lun;
        u32 scsi_result;
-       u64 scsi_cmnd;
-#define ZFCP_DBF_SCSI_OPCODE   16
-       u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
        u8 scsi_retries;
        u8 scsi_allowed;
-       u64 fsf_reqid;
-       u32 fsf_seqno;
-       u64 fsf_issued;
-       u64 old_fsf_reqid;
-       u8 rsp_validity;
-       u8 rsp_scsi_status;
-       u32 rsp_resid;
-       u8 rsp_code;
-#define ZFCP_DBF_SCSI_FCP_SNS_INFO     16
-#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256
-       u32 sns_info_len;
-       u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
-} __attribute__ ((packed));
+       u8 fcp_rsp_info;
+#define ZFCP_DBF_SCSI_OPCODE   16
+       u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
+       u64 fsf_req_id;
+       u64 host_scribble;
+       u16 pl_len;
+       struct fcp_resp_with_ext fcp_rsp;
+} __packed;
 
+/**
+ * struct zfcp_dbf_pay - trace record for unformatted payload information
+ * @area: area this record is originated from
+ * @counter: ascending record number
+ * @fsf_req_id: request id of fsf request
+ * @data: unformatted data
+ */
+struct zfcp_dbf_pay {
+       u8 counter;
+       char area[ZFCP_DBF_TAG_LEN];
+       u64 fsf_req_id;
+#define ZFCP_DBF_PAY_MAX_REC 0x100
+       char data[ZFCP_DBF_PAY_MAX_REC];
+} __packed;
+
+/**
+ * struct zfcp_dbf - main dbf trace structure
+ * @pay: reference to payload trace area
+ * @rec: reference to recovery trace area
+ * @hba: reference to hba trace area
+ * @san: reference to san trace area
+ * @scsi: reference to scsi trace area
+ * @pay_lock: lock protecting payload trace buffer
+ * @rec_lock: lock protecting recovery trace buffer
+ * @hba_lock: lock protecting hba trace buffer
+ * @san_lock: lock protecting san trace buffer
+ * @scsi_lock: lock protecting scsi trace buffer
+ * @pay_buf: pre-allocated buffer for payload
+ * @rec_buf: pre-allocated buffer for recovery
+ * @hba_buf: pre-allocated buffer for hba
+ * @san_buf: pre-allocated buffer for san
+ * @scsi_buf: pre-allocated buffer for scsi
+ */
 struct zfcp_dbf {
+       debug_info_t                    *pay;
        debug_info_t                    *rec;
        debug_info_t                    *hba;
        debug_info_t                    *san;
        debug_info_t                    *scsi;
+       spinlock_t                      pay_lock;
        spinlock_t                      rec_lock;
        spinlock_t                      hba_lock;
        spinlock_t                      san_lock;
        spinlock_t                      scsi_lock;
-       struct zfcp_dbf_rec_record      rec_buf;
-       struct zfcp_dbf_hba_record      hba_buf;
-       struct zfcp_dbf_san_record      san_buf;
-       struct zfcp_dbf_scsi_record     scsi_buf;
-       struct zfcp_adapter             *adapter;
+       struct zfcp_dbf_pay             pay_buf;
+       struct zfcp_dbf_rec             rec_buf;
+       struct zfcp_dbf_hba             hba_buf;
+       struct zfcp_dbf_san             san_buf;
+       struct zfcp_dbf_scsi            scsi_buf;
 };
 
 static inline
-void zfcp_dbf_hba_fsf_resp(const char *tag2, int level,
-                          struct zfcp_fsf_req *req, struct zfcp_dbf *dbf)
+void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
 {
-       if (level <= dbf->hba->level)
-               _zfcp_dbf_hba_fsf_response(tag2, level, req, dbf);
+       if (level <= req->adapter->dbf->hba->level)
+               zfcp_dbf_hba_fsf_res(tag, req);
 }
 
 /**
  * zfcp_dbf_hba_fsf_response - trace event for request completion
- * @fsf_req: request that has been completed
+ * @req: request that has been completed
  */
-static inline void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
+static inline
+void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
 {
-       struct zfcp_dbf *dbf = req->adapter->dbf;
        struct fsf_qtcb *qtcb = req->qtcb;
 
        if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
            (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
-               zfcp_dbf_hba_fsf_resp("perr", 1, req, dbf);
+               zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
 
        } else if (qtcb->header.fsf_status != FSF_GOOD) {
-               zfcp_dbf_hba_fsf_resp("ferr", 1, req, dbf);
+               zfcp_dbf_hba_fsf_resp("fs_ferr", 1, req);
 
        } else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
                   (req->fsf_command == FSF_QTCB_OPEN_LUN)) {
-               zfcp_dbf_hba_fsf_resp("open", 4, req, dbf);
+               zfcp_dbf_hba_fsf_resp("fs_open", 4, req);
 
        } else if (qtcb->header.log_length) {
-               zfcp_dbf_hba_fsf_resp("qtcb", 5, req, dbf);
+               zfcp_dbf_hba_fsf_resp("fs_qtcb", 5, req);
 
        } else {
-               zfcp_dbf_hba_fsf_resp("norm", 6, req, dbf);
+               zfcp_dbf_hba_fsf_resp("fs_norm", 6, req);
        }
- }
-
-/**
- * zfcp_dbf_hba_fsf_unsol - trace event for an unsolicited status buffer
- * @tag: tag indicating which kind of unsolicited status has been received
- * @dbf: reference to dbf structure
- * @status_buffer: buffer containing payload of unsolicited status
- */
-static inline
-void zfcp_dbf_hba_fsf_unsol(const char *tag, struct zfcp_dbf *dbf,
-                           struct fsf_status_read_buffer *buf)
-{
-       int level = 2;
-
-       if (level <= dbf->hba->level)
-               _zfcp_dbf_hba_fsf_unsol(tag, level, dbf, buf);
 }
 
 static inline
-void zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
-                  struct zfcp_dbf *dbf, struct scsi_cmnd *scmd,
-                  struct zfcp_fsf_req *req, unsigned long old_id)
+void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
+                  struct zfcp_fsf_req *req)
 {
-       if (level <= dbf->scsi->level)
-               _zfcp_dbf_scsi(tag, tag2, level, dbf, scmd, req, old_id);
+       struct zfcp_adapter *adapter = (struct zfcp_adapter *)
+                                       scmd->device->host->hostdata[0];
+
+       if (level <= adapter->dbf->scsi->level)
+               zfcp_dbf_scsi(tag, scmd, req);
 }
 
 /**
  * zfcp_dbf_scsi_result - trace event for SCSI command completion
- * @dbf: adapter dbf trace
  * @scmd: SCSI command pointer
  * @req: FSF request used to issue SCSI command
  */
 static inline
-void zfcp_dbf_scsi_result(struct zfcp_dbf *dbf, struct scsi_cmnd *scmd,
-                         struct zfcp_fsf_req *req)
+void zfcp_dbf_scsi_result(struct scsi_cmnd *scmd, struct zfcp_fsf_req *req)
 {
        if (scmd->result != 0)
-               zfcp_dbf_scsi("rslt", "erro", 3, dbf, scmd, req, 0);
+               _zfcp_dbf_scsi("rsl_err", 3, scmd, req);
        else if (scmd->retries > 0)
-               zfcp_dbf_scsi("rslt", "retr", 4, dbf, scmd, req, 0);
+               _zfcp_dbf_scsi("rsl_ret", 4, scmd, req);
        else
-               zfcp_dbf_scsi("rslt", "norm", 6, dbf, scmd, req, 0);
+               _zfcp_dbf_scsi("rsl_nor", 6, scmd, req);
 }
 
 /**
  * zfcp_dbf_scsi_fail_send - trace event for failure to send SCSI command
- * @dbf: adapter dbf trace
  * @scmd: SCSI command pointer
  */
 static inline
-void zfcp_dbf_scsi_fail_send(struct zfcp_dbf *dbf, struct scsi_cmnd *scmd)
+void zfcp_dbf_scsi_fail_send(struct scsi_cmnd *scmd)
 {
-       zfcp_dbf_scsi("rslt", "fail", 4, dbf, scmd, NULL, 0);
+       _zfcp_dbf_scsi("rsl_fai", 4, scmd, NULL);
 }
 
 /**
  * zfcp_dbf_scsi_abort - trace event for SCSI command abort
  * @tag: tag indicating success or failure of abort operation
- * @adapter: adapter thas has been used to issue SCSI command to be aborted
  * @scmd: SCSI command to be aborted
- * @new_req: request containing abort (might be NULL)
- * @old_id: identifier of request containg SCSI command to be aborted
+ * @fsf_req: request containing abort (might be NULL)
  */
 static inline
-void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf,
-                        struct scsi_cmnd *scmd, struct zfcp_fsf_req *new_req,
-                        unsigned long old_id)
+void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd,
+                        struct zfcp_fsf_req *fsf_req)
 {
-       zfcp_dbf_scsi("abrt", tag, 1, dbf, scmd, new_req, old_id);
+       _zfcp_dbf_scsi(tag, 1, scmd, fsf_req);
 }
 
 /**
@@ -352,12 +366,17 @@ void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf,
  * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
  */
 static inline
-void zfcp_dbf_scsi_devreset(const char *tag, struct scsi_cmnd *scmnd, u8 flag)
+void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag)
 {
-       struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device);
+       char tmp_tag[ZFCP_DBF_TAG_LEN];
+
+       if (flag == FCP_TMF_TGT_RESET)
+               memcpy(tmp_tag, "tr_", 3);
+       else
+               memcpy(tmp_tag, "lr_", 3);
 
-       zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
-                     zfcp_sdev->port->adapter->dbf, scmnd, NULL, 0);
+       memcpy(&tmp_tag[3], tag, 4);
+       _zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL);
 }
 
 #endif /* ZFCP_DBF_H */
index d37c7331f244f1463c154a05ec9649306fe0c358..e003e306f870aebd0ea3a7b41265509dc35a74ee 100644 (file)
@@ -76,9 +76,9 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
        struct zfcp_adapter *adapter = act->adapter;
 
        list_move(&act->list, &act->adapter->erp_ready_head);
-       zfcp_dbf_rec_action("erardy1", act);
+       zfcp_dbf_rec_run("erardy1", act);
        wake_up(&adapter->erp_ready_wq);
-       zfcp_dbf_rec_thread("erardy2", adapter->dbf);
+       zfcp_dbf_rec_run("erardy2", act);
 }
 
 static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act)
@@ -156,6 +156,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
                if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) ||
                      a_status & ZFCP_STATUS_COMMON_ERP_FAILED)
                        return 0;
+               if (p_status & ZFCP_STATUS_COMMON_NOESC)
+                       return need;
                if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED))
                        need = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
                /* fall through */
@@ -188,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
                                &zfcp_sdev->status);
                erp_action = &zfcp_sdev->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+               erp_action->port = port;
+               erp_action->sdev = sdev;
                if (!(atomic_read(&zfcp_sdev->status) &
                      ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -200,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                zfcp_erp_action_dismiss_port(port);
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
                erp_action = &port->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+               erp_action->port = port;
                if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
                break;
@@ -209,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                zfcp_erp_action_dismiss_adapter(adapter);
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
                erp_action = &adapter->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
                if (!(atomic_read(&adapter->status) &
                      ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -218,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                return NULL;
        }
 
-       memset(erp_action, 0, sizeof(struct zfcp_erp_action));
        erp_action->adapter = adapter;
-       erp_action->port = port;
-       erp_action->sdev = sdev;
        erp_action->action = need;
        erp_action->status = act_status;
 
@@ -231,10 +236,10 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
 static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
                                   struct zfcp_port *port,
                                   struct scsi_device *sdev,
-                                  char *id, void *ref, u32 act_status)
+                                  char *id, u32 act_status)
 {
        int retval = 1, need;
-       struct zfcp_erp_action *act = NULL;
+       struct zfcp_erp_action *act;
 
        if (!adapter->erp_thread)
                return -EIO;
@@ -250,15 +255,14 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
        ++adapter->erp_total_count;
        list_add_tail(&act->list, &adapter->erp_ready_head);
        wake_up(&adapter->erp_ready_wq);
-       zfcp_dbf_rec_thread("eracte1", adapter->dbf);
        retval = 0;
  out:
-       zfcp_dbf_rec_trigger(id, ref, want, need, act, adapter, port, sdev);
+       zfcp_dbf_rec_trig(id, adapter, port, sdev, want, need);
        return retval;
 }
 
 static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
-                                   int clear_mask, char *id, void *ref)
+                                   int clear_mask, char *id)
 {
        zfcp_erp_adapter_block(adapter, clear_mask);
        zfcp_scsi_schedule_rports_block(adapter);
@@ -270,7 +274,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
                return -EIO;
        }
        return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
-                                      adapter, NULL, NULL, id, ref, 0);
+                                      adapter, NULL, NULL, id, 0);
 }
 
 /**
@@ -278,10 +282,8 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
  * @adapter: Adapter to reopen.
  * @clear: Status flags to clear.
  * @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
  */
-void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
-                            char *id, void *ref)
+void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, char *id)
 {
        unsigned long flags;
 
@@ -294,7 +296,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
                                            ZFCP_STATUS_COMMON_ERP_FAILED);
        else
                zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
-                                       NULL, NULL, id, ref, 0);
+                                       NULL, NULL, id, 0);
        write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
@@ -303,13 +305,12 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
  * @adapter: Adapter to shut down.
  * @clear: Status flags to clear.
  * @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
  */
 void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
-                              char *id, void *ref)
+                              char *id)
 {
        int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
-       zfcp_erp_adapter_reopen(adapter, clear | flags, id, ref);
+       zfcp_erp_adapter_reopen(adapter, clear | flags, id);
 }
 
 /**
@@ -317,13 +318,11 @@ void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
  * @port: Port to shut down.
  * @clear: Status flags to clear.
  * @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
  */
-void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id,
-                           void *ref)
+void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id)
 {
        int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
-       zfcp_erp_port_reopen(port, clear | flags, id, ref);
+       zfcp_erp_port_reopen(port, clear | flags, id);
 }
 
 static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
@@ -332,8 +331,8 @@ static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
                                    ZFCP_STATUS_COMMON_UNBLOCKED | clear);
 }
 
-static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
-                                        int clear, char *id, void *ref)
+static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear,
+                                        char *id)
 {
        zfcp_erp_port_block(port, clear);
        zfcp_scsi_schedule_rport_block(port);
@@ -342,28 +341,26 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
                return;
 
        zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
-                               port->adapter, port, NULL, id, ref, 0);
+                               port->adapter, port, NULL, id, 0);
 }
 
 /**
  * zfcp_erp_port_forced_reopen - Forced close of port and open again
  * @port: Port to force close and to reopen.
+ * @clear: Status flags to clear.
  * @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
  */
-void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id,
-                                void *ref)
+void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id)
 {
        unsigned long flags;
        struct zfcp_adapter *adapter = port->adapter;
 
        write_lock_irqsave(&adapter->erp_lock, flags);
-       _zfcp_erp_port_forced_reopen(port, clear, id, ref);
+       _zfcp_erp_port_forced_reopen(port, clear, id);
        write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
-static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
-                                void *ref)
+static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
 {
        zfcp_erp_port_block(port, clear);
        zfcp_scsi_schedule_rport_block(port);
@@ -375,24 +372,25 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
        }
 
        return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
-                                      port->adapter, port, NULL, id, ref, 0);
+                                      port->adapter, port, NULL, id, 0);
 }
 
 /**
  * zfcp_erp_port_reopen - trigger remote port recovery
  * @port: port to recover
  * @clear_mask: flags in port status to be cleared
+ * @id: Id for debug trace event.
  *
  * Returns 0 if recovery has been triggered, < 0 if not.
  */
-int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref)
+int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
 {
        int retval;
        unsigned long flags;
        struct zfcp_adapter *adapter = port->adapter;
 
        write_lock_irqsave(&adapter->erp_lock, flags);
-       retval = _zfcp_erp_port_reopen(port, clear, id, ref);
+       retval = _zfcp_erp_port_reopen(port, clear, id);
        write_unlock_irqrestore(&adapter->erp_lock, flags);
 
        return retval;
@@ -405,7 +403,7 @@ static void zfcp_erp_lun_block(struct scsi_device *sdev, int clear_mask)
 }
 
 static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
-                                void *ref, u32 act_status)
+                                u32 act_status)
 {
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
        struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
@@ -416,17 +414,18 @@ static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
                return;
 
        zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter,
-                               zfcp_sdev->port, sdev, id, ref, act_status);
+                               zfcp_sdev->port, sdev, id, act_status);
 }
 
 /**
  * zfcp_erp_lun_reopen - initiate reopen of a LUN
  * @sdev: SCSI device / LUN to be reopened
  * @clear_mask: specifies flags in LUN status to be cleared
+ * @id: Id for debug trace event.
+ *
  * Return: 0 on success, < 0 on error
  */
-void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
-                        void *ref)
+void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id)
 {
        unsigned long flags;
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
@@ -434,7 +433,7 @@ void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
        struct zfcp_adapter *adapter = port->adapter;
 
        write_lock_irqsave(&adapter->erp_lock, flags);
-       _zfcp_erp_lun_reopen(sdev, clear, id, ref, 0);
+       _zfcp_erp_lun_reopen(sdev, clear, id, 0);
        write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
@@ -443,13 +442,11 @@ void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
  * @sdev: SCSI device / LUN to shut down.
  * @clear: Status flags to clear.
  * @id: Id for debug trace event.
- * @ref: Reference for debug trace event.
  */
-void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *id,
-                          void *ref)
+void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *id)
 {
        int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
-       zfcp_erp_lun_reopen(sdev, clear | flags, id, ref);
+       zfcp_erp_lun_reopen(sdev, clear | flags, id);
 }
 
 /**
@@ -471,7 +468,7 @@ void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *id)
        int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
 
        write_lock_irqsave(&adapter->erp_lock, flags);
-       _zfcp_erp_lun_reopen(sdev, clear, id, NULL, ZFCP_STATUS_ERP_NO_REF);
+       _zfcp_erp_lun_reopen(sdev, clear, id, ZFCP_STATUS_ERP_NO_REF);
        write_unlock_irqrestore(&adapter->erp_lock, flags);
 
        zfcp_erp_wait(adapter);
@@ -485,14 +482,14 @@ static int status_change_set(unsigned long mask, atomic_t *status)
 static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
 {
        if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status))
-               zfcp_dbf_rec_adapter("eraubl1", NULL, adapter->dbf);
+               zfcp_dbf_rec_run("eraubl1", &adapter->erp_action);
        atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);
 }
 
 static void zfcp_erp_port_unblock(struct zfcp_port *port)
 {
        if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status))
-               zfcp_dbf_rec_port("erpubl1", NULL, port);
+               zfcp_dbf_rec_run("erpubl1", &port->erp_action);
        atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);
 }
 
@@ -501,14 +498,14 @@ static void zfcp_erp_lun_unblock(struct scsi_device *sdev)
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
 
        if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &zfcp_sdev->status))
-               zfcp_dbf_rec_lun("erlubl1", NULL, sdev);
+               zfcp_dbf_rec_run("erlubl1", &sdev_to_zfcp(sdev)->erp_action);
        atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &zfcp_sdev->status);
 }
 
 static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
 {
        list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
-       zfcp_dbf_rec_action("erator1", erp_action);
+       zfcp_dbf_rec_run("erator1", erp_action);
 }
 
 static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
@@ -525,11 +522,11 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
                if (act->status & (ZFCP_STATUS_ERP_DISMISSED |
                                   ZFCP_STATUS_ERP_TIMEDOUT)) {
                        req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
-                       zfcp_dbf_rec_action("erscf_1", act);
+                       zfcp_dbf_rec_run("erscf_1", act);
                        req->erp_action = NULL;
                }
                if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
-                       zfcp_dbf_rec_action("erscf_2", act);
+                       zfcp_dbf_rec_run("erscf_2", act);
                if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED)
                        act->fsf_req_id = 0;
        } else
@@ -580,40 +577,40 @@ static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
 }
 
 static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
-                                     int clear, char *id, void *ref)
+                                     int clear, char *id)
 {
        struct zfcp_port *port;
 
        read_lock(&adapter->port_list_lock);
        list_for_each_entry(port, &adapter->port_list, list)
-               _zfcp_erp_port_reopen(port, clear, id, ref);
+               _zfcp_erp_port_reopen(port, clear, id);
        read_unlock(&adapter->port_list_lock);
 }
 
 static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear,
-                                    char *id, void *ref)
+                                    char *id)
 {
        struct scsi_device *sdev;
 
        shost_for_each_device(sdev, port->adapter->scsi_host)
                if (sdev_to_zfcp(sdev)->port == port)
-                       _zfcp_erp_lun_reopen(sdev, clear, id, ref, 0);
+                       _zfcp_erp_lun_reopen(sdev, clear, id, 0);
 }
 
 static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
 {
        switch (act->action) {
        case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
-               _zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1", NULL);
+               _zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1");
                break;
        case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
-               _zfcp_erp_port_forced_reopen(act->port, 0, "ersff_2", NULL);
+               _zfcp_erp_port_forced_reopen(act->port, 0, "ersff_2");
                break;
        case ZFCP_ERP_ACTION_REOPEN_PORT:
-               _zfcp_erp_port_reopen(act->port, 0, "ersff_3", NULL);
+               _zfcp_erp_port_reopen(act->port, 0, "ersff_3");
                break;
        case ZFCP_ERP_ACTION_REOPEN_LUN:
-               _zfcp_erp_lun_reopen(act->sdev, 0, "ersff_4", NULL, 0);
+               _zfcp_erp_lun_reopen(act->sdev, 0, "ersff_4", 0);
                break;
        }
 }
@@ -622,13 +619,13 @@ static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act)
 {
        switch (act->action) {
        case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
-               _zfcp_erp_port_reopen_all(act->adapter, 0, "ersfs_1", NULL);
+               _zfcp_erp_port_reopen_all(act->adapter, 0, "ersfs_1");
                break;
        case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
-               _zfcp_erp_port_reopen(act->port, 0, "ersfs_2", NULL);
+               _zfcp_erp_port_reopen(act->port, 0, "ersfs_2");
                break;
        case ZFCP_ERP_ACTION_REOPEN_PORT:
-               _zfcp_erp_lun_reopen_all(act->port, 0, "ersfs_3", NULL);
+               _zfcp_erp_lun_reopen_all(act->port, 0, "ersfs_3");
                break;
        }
 }
@@ -647,17 +644,6 @@ static void zfcp_erp_wakeup(struct zfcp_adapter *adapter)
        read_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
-static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act)
-{
-       struct zfcp_qdio *qdio = act->adapter->qdio;
-
-       if (zfcp_qdio_open(qdio))
-               return ZFCP_ERP_FAILED;
-       init_waitqueue_head(&qdio->req_q_wq);
-       atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &act->adapter->status);
-       return ZFCP_ERP_SUCCEEDED;
-}
-
 static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter)
 {
        struct zfcp_port *port;
@@ -665,7 +651,7 @@ static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter)
                                 adapter->peer_d_id);
        if (IS_ERR(port)) /* error or port already attached */
                return;
-       _zfcp_erp_port_reopen(port, 0, "ereptp1", NULL);
+       _zfcp_erp_port_reopen(port, 0, "ereptp1");
 }
 
 static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
@@ -688,10 +674,8 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
                        return ZFCP_ERP_FAILED;
                }
 
-               zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf);
                wait_event(adapter->erp_ready_wq,
                           !list_empty(&adapter->erp_ready_head));
-               zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf);
                if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT)
                        break;
 
@@ -730,10 +714,10 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
        if (ret)
                return ZFCP_ERP_FAILED;
 
-       zfcp_dbf_rec_thread_lock("erasox1", adapter->dbf);
+       zfcp_dbf_rec_run("erasox1", act);
        wait_event(adapter->erp_ready_wq,
                   !list_empty(&adapter->erp_ready_head));
-       zfcp_dbf_rec_thread_lock("erasox2", adapter->dbf);
+       zfcp_dbf_rec_run("erasox2", act);
        if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
                return ZFCP_ERP_FAILED;
 
@@ -783,7 +767,7 @@ static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *act)
 {
        struct zfcp_adapter *adapter = act->adapter;
 
-       if (zfcp_erp_adapter_strategy_open_qdio(act)) {
+       if (zfcp_qdio_open(adapter->qdio)) {
                atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
                                  ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
                                  &adapter->status);
@@ -1161,7 +1145,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
                if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) {
                        _zfcp_erp_adapter_reopen(adapter,
                                                 ZFCP_STATUS_COMMON_ERP_FAILED,
-                                                "ersscg1", NULL);
+                                                "ersscg1");
                        return ZFCP_ERP_EXIT;
                }
                break;
@@ -1171,7 +1155,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
                if (zfcp_erp_strat_change_det(&port->status, erp_status)) {
                        _zfcp_erp_port_reopen(port,
                                              ZFCP_STATUS_COMMON_ERP_FAILED,
-                                             "ersscg2", NULL);
+                                             "ersscg2");
                        return ZFCP_ERP_EXIT;
                }
                break;
@@ -1181,7 +1165,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
                if (zfcp_erp_strat_change_det(&zfcp_sdev->status, erp_status)) {
                        _zfcp_erp_lun_reopen(sdev,
                                             ZFCP_STATUS_COMMON_ERP_FAILED,
-                                            "ersscg3", NULL, 0);
+                                            "ersscg3", 0);
                        return ZFCP_ERP_EXIT;
                }
                break;
@@ -1201,7 +1185,7 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
        }
 
        list_del(&erp_action->list);
-       zfcp_dbf_rec_action("eractd1", erp_action);
+       zfcp_dbf_rec_run("eractd1", erp_action);
 
        switch (erp_action->action) {
        case ZFCP_ERP_ACTION_REOPEN_LUN:
@@ -1308,7 +1292,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
                        erp_action->status |= ZFCP_STATUS_ERP_LOWMEM;
                }
                if (adapter->erp_total_count == adapter->erp_low_mem_count)
-                       _zfcp_erp_adapter_reopen(adapter, 0, "erstgy1", NULL);
+                       _zfcp_erp_adapter_reopen(adapter, 0, "erstgy1");
                else {
                        zfcp_erp_strategy_memwait(erp_action);
                        retval = ZFCP_ERP_CONTINUES;
@@ -1352,11 +1336,9 @@ static int zfcp_erp_thread(void *data)
        unsigned long flags;
 
        for (;;) {
-               zfcp_dbf_rec_thread_lock("erthrd1", adapter->dbf);
                wait_event_interruptible(adapter->erp_ready_wq,
                           !list_empty(&adapter->erp_ready_head) ||
                           kthread_should_stop());
-               zfcp_dbf_rec_thread_lock("erthrd2", adapter->dbf);
 
                if (kthread_should_stop())
                        break;
index bf8f3e5148397858aae35be598d79be6d6853707..6e325284fbe774b837a97a0fa9450af742ab829f 100644 (file)
@@ -45,47 +45,33 @@ extern void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *);
 
 /* zfcp_dbf.c */
 extern int zfcp_dbf_adapter_register(struct zfcp_adapter *);
-extern void zfcp_dbf_adapter_unregister(struct zfcp_dbf *);
-extern void zfcp_dbf_rec_thread(char *, struct zfcp_dbf *);
-extern void zfcp_dbf_rec_thread_lock(char *, struct zfcp_dbf *);
-extern void zfcp_dbf_rec_adapter(char *, void *, struct zfcp_dbf *);
-extern void zfcp_dbf_rec_port(char *, void *, struct zfcp_port *);
-extern void zfcp_dbf_rec_lun(char *, void *, struct scsi_device *);
-extern void zfcp_dbf_rec_trigger(char *, void *, u8, u8, void *,
-                                struct zfcp_adapter *, struct zfcp_port *,
-                                struct scsi_device *);
-extern void zfcp_dbf_rec_action(char *, struct zfcp_erp_action *);
-extern void _zfcp_dbf_hba_fsf_response(const char *, int, struct zfcp_fsf_req *,
-                                      struct zfcp_dbf *);
-extern void _zfcp_dbf_hba_fsf_unsol(const char *, int level, struct zfcp_dbf *,
-                                         struct fsf_status_read_buffer *);
-extern void zfcp_dbf_hba_qdio(struct zfcp_dbf *, unsigned int, int, int);
+extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *);
+extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
+                             struct zfcp_port *, struct scsi_device *, u8, u8);
+extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
+extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
 extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *, u32);
-extern void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_els_request(struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_els_response(struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *);
-extern void _zfcp_dbf_scsi(const char *, const char *, int, struct zfcp_dbf *,
-                          struct scsi_cmnd *, struct zfcp_fsf_req *,
-                          unsigned long);
+extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
+extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_scsi(char *, struct scsi_cmnd *, struct zfcp_fsf_req *);
 
 /* zfcp_erp.c */
 extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
 extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32);
-extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *, void *);
-extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *,
-                                     void *);
+extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *);
+extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *);
 extern void zfcp_erp_set_port_status(struct zfcp_port *, u32);
 extern void zfcp_erp_clear_port_status(struct zfcp_port *, u32);
-extern int  zfcp_erp_port_reopen(struct zfcp_port *, int, char *, void *);
-extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *, void *);
-extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *,
-                                       void *);
+extern int  zfcp_erp_port_reopen(struct zfcp_port *, int, char *);
+extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *);
+extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *);
 extern void zfcp_erp_set_lun_status(struct scsi_device *, u32);
 extern void zfcp_erp_clear_lun_status(struct scsi_device *, u32);
-extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *, void *);
-extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *, void *);
+extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *);
+extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *);
 extern void zfcp_erp_lun_shutdown_wait(struct scsi_device *, char *);
 extern int  zfcp_erp_thread_setup(struct zfcp_adapter *);
 extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
@@ -149,6 +135,8 @@ extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *, struct zfcp_qdio_req *,
 extern int zfcp_qdio_open(struct zfcp_qdio *);
 extern void zfcp_qdio_close(struct zfcp_qdio *);
 extern void zfcp_qdio_siosl(struct zfcp_adapter *);
+extern struct zfcp_fsf_req *zfcp_fsf_get_req(struct zfcp_qdio *,
+                                            struct qdio_buffer *);
 
 /* zfcp_scsi.c */
 extern struct zfcp_data zfcp_data;
index 86fd905df48b29041a1cc4ac3268aa56b2489430..30cf91a787a3315e046957c41483c4c50948b858 100644 (file)
@@ -174,7 +174,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
                if (!port->d_id)
                        zfcp_erp_port_reopen(port,
                                             ZFCP_STATUS_COMMON_ERP_FAILED,
-                                            "fcrscn1", NULL);
+                                            "fcrscn1");
        }
        read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
@@ -215,7 +215,7 @@ static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
        read_lock_irqsave(&adapter->port_list_lock, flags);
        list_for_each_entry(port, &adapter->port_list, list)
                if (port->wwpn == wwpn) {
-                       zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req);
+                       zfcp_erp_port_forced_reopen(port, 0, "fciwwp1");
                        break;
                }
        read_unlock_irqrestore(&adapter->port_list_lock, flags);
@@ -251,7 +251,7 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
                (struct fsf_status_read_buffer *) fsf_req->data;
        unsigned int els_type = status_buffer->payload.data[0];
 
-       zfcp_dbf_san_incoming_els(fsf_req);
+       zfcp_dbf_san_in_els("fciels1", fsf_req);
        if (els_type == ELS_PLOGI)
                zfcp_fc_incoming_plogi(fsf_req);
        else if (els_type == ELS_LOGO)
@@ -360,7 +360,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
        ret = zfcp_fc_ns_gid_pn(port);
        if (ret) {
                /* could not issue gid_pn for some reason */
-               zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1", NULL);
+               zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1");
                goto out;
        }
 
@@ -369,7 +369,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work)
                goto out;
        }
 
-       zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
+       zfcp_erp_port_reopen(port, 0, "fcgpn_3");
 out:
        put_device(&port->dev);
 }
@@ -426,7 +426,7 @@ static void zfcp_fc_adisc_handler(void *data)
        if (adisc->els.status) {
                /* request rejected or timed out */
                zfcp_erp_port_forced_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
-                                           "fcadh_1", NULL);
+                                           "fcadh_1");
                goto out;
        }
 
@@ -436,7 +436,7 @@ static void zfcp_fc_adisc_handler(void *data)
        if ((port->wwpn != adisc_resp->adisc_wwpn) ||
            !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) {
                zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
-                                    "fcadh_2", NULL);
+                                    "fcadh_2");
                goto out;
        }
 
@@ -507,7 +507,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
 
        /* send of ADISC was not possible */
        atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
-       zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
+       zfcp_erp_port_forced_reopen(port, 0, "fcltwk1");
 
 out:
        put_device(&port->dev);
@@ -659,7 +659,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
                port = zfcp_port_enqueue(adapter, acc->fp_wwpn,
                                         ZFCP_STATUS_COMMON_NOESC, d_id);
                if (!IS_ERR(port))
-                       zfcp_erp_port_reopen(port, 0, "fcegpf1", NULL);
+                       zfcp_erp_port_reopen(port, 0, "fcegpf1");
                else if (PTR_ERR(port) != -EEXIST)
                        ret = PTR_ERR(port);
        }
@@ -671,7 +671,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
        write_unlock_irqrestore(&adapter->port_list_lock, flags);
 
        list_for_each_entry_safe(port, tmp, &remove_lh, list) {
-               zfcp_erp_port_shutdown(port, 0, "fcegpf2", NULL);
+               zfcp_erp_port_shutdown(port, 0, "fcegpf2");
                zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
        }
 
index be0317457147fc4a891f4b0be67c8116b98526b1..60ff9d172c79a60b56a7c9f1ec2970ffea4dde69 100644 (file)
@@ -23,7 +23,7 @@ static void zfcp_fsf_request_timeout_handler(unsigned long data)
        struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
        zfcp_qdio_siosl(adapter);
        zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
-                               "fsrth_1", NULL);
+                               "fsrth_1");
 }
 
 static void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req,
@@ -65,7 +65,7 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req)
 {
        dev_err(&req->adapter->ccw_device->dev, "FCP device not "
                "operational because of an unsupported FC class\n");
-       zfcp_erp_adapter_shutdown(req->adapter, 0, "fscns_1", req);
+       zfcp_erp_adapter_shutdown(req->adapter, 0, "fscns_1");
        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 }
 
@@ -98,7 +98,7 @@ static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
        read_lock_irqsave(&adapter->port_list_lock, flags);
        list_for_each_entry(port, &adapter->port_list, list)
                if (port->d_id == d_id) {
-                       zfcp_erp_port_reopen(port, 0, "fssrpc1", req);
+                       zfcp_erp_port_reopen(port, 0, "fssrpc1");
                        break;
                }
        read_unlock_irqrestore(&adapter->port_list_lock, flags);
@@ -211,13 +211,13 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
        struct fsf_status_read_buffer *sr_buf = req->data;
 
        if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
-               zfcp_dbf_hba_fsf_unsol("dism", adapter->dbf, sr_buf);
+               zfcp_dbf_hba_fsf_uss("fssrh_1", req);
                mempool_free(sr_buf, adapter->pool.status_read_data);
                zfcp_fsf_req_free(req);
                return;
        }
 
-       zfcp_dbf_hba_fsf_unsol("read", adapter->dbf, sr_buf);
+       zfcp_dbf_hba_fsf_uss("fssrh_2", req);
 
        switch (sr_buf->status_type) {
        case FSF_STATUS_READ_PORT_CLOSED:
@@ -232,7 +232,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
                dev_warn(&adapter->ccw_device->dev,
                         "The error threshold for checksum statistics "
                         "has been exceeded\n");
-               zfcp_dbf_hba_berr(adapter->dbf, req);
+               zfcp_dbf_hba_bit_err("fssrh_3", req);
                break;
        case FSF_STATUS_READ_LINK_DOWN:
                zfcp_fsf_status_read_link_down(req);
@@ -247,7 +247,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
                zfcp_erp_adapter_reopen(adapter,
                                        ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
                                        ZFCP_STATUS_COMMON_ERP_FAILED,
-                                       "fssrh_2", req);
+                                       "fssrh_2");
                zfcp_fc_enqueue_event(adapter, FCH_EVT_LINKUP, 0);
 
                break;
@@ -287,7 +287,7 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
                        "The FCP adapter reported a problem "
                        "that cannot be recovered\n");
                zfcp_qdio_siosl(req->adapter);
-               zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1", req);
+               zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1");
                break;
        }
        /* all non-return stats set FSFREQ_ERROR*/
@@ -304,7 +304,7 @@ static void zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *req)
                dev_err(&req->adapter->ccw_device->dev,
                        "The FCP adapter does not recognize the command 0x%x\n",
                        req->qtcb->header.fsf_command);
-               zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfse_1", req);
+               zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfse_1");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -335,17 +335,17 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
                        "QTCB version 0x%x not supported by FCP adapter "
                        "(0x%x to 0x%x)\n", FSF_QTCB_CURRENT_VERSION,
                        psq->word[0], psq->word[1]);
-               zfcp_erp_adapter_shutdown(adapter, 0, "fspse_1", req);
+               zfcp_erp_adapter_shutdown(adapter, 0, "fspse_1");
                break;
        case FSF_PROT_ERROR_STATE:
        case FSF_PROT_SEQ_NUMB_ERROR:
-               zfcp_erp_adapter_reopen(adapter, 0, "fspse_2", req);
+               zfcp_erp_adapter_reopen(adapter, 0, "fspse_2");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_PROT_UNSUPP_QTCB_TYPE:
                dev_err(&adapter->ccw_device->dev,
                        "The QTCB type is not supported by the FCP adapter\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, "fspse_3", req);
+               zfcp_erp_adapter_shutdown(adapter, 0, "fspse_3");
                break;
        case FSF_PROT_HOST_CONNECTION_INITIALIZING:
                atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
@@ -355,12 +355,12 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
                dev_err(&adapter->ccw_device->dev,
                        "0x%Lx is an ambiguous request identifier\n",
                        (unsigned long long)qtcb->bottom.support.req_handle);
-               zfcp_erp_adapter_shutdown(adapter, 0, "fspse_4", req);
+               zfcp_erp_adapter_shutdown(adapter, 0, "fspse_4");
                break;
        case FSF_PROT_LINK_DOWN:
                zfcp_fsf_link_down_info_eval(req, &psq->link_down_info);
                /* go through reopen to flush pending requests */
-               zfcp_erp_adapter_reopen(adapter, 0, "fspse_6", req);
+               zfcp_erp_adapter_reopen(adapter, 0, "fspse_6");
                break;
        case FSF_PROT_REEST_QUEUE:
                /* All ports should be marked as ready to run again */
@@ -369,14 +369,14 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
                zfcp_erp_adapter_reopen(adapter,
                                        ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
                                        ZFCP_STATUS_COMMON_ERP_FAILED,
-                                       "fspse_8", req);
+                                       "fspse_8");
                break;
        default:
                dev_err(&adapter->ccw_device->dev,
                        "0x%x is not a valid transfer protocol status\n",
                        qtcb->prefix.prot_status);
                zfcp_qdio_siosl(adapter);
-               zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9", req);
+               zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9");
        }
        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 }
@@ -482,7 +482,7 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
                dev_err(&adapter->ccw_device->dev,
                        "Unknown or unsupported arbitrated loop "
                        "fibre channel topology detected\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, "fsece_1", req);
+               zfcp_erp_adapter_shutdown(adapter, 0, "fsece_1");
                return -EIO;
        }
 
@@ -518,7 +518,7 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
                                "FCP adapter maximum QTCB size (%d bytes) "
                                "is too small\n",
                                bottom->max_qtcb_size);
-                       zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh1", req);
+                       zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh1");
                        return;
                }
                atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
@@ -536,7 +536,7 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
                        &qtcb->header.fsf_status_qual.link_down_info);
                break;
        default:
-               zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3", req);
+               zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3");
                return;
        }
 
@@ -552,14 +552,14 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
                dev_err(&adapter->ccw_device->dev,
                        "The FCP adapter only supports newer "
                        "control block versions\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh4", req);
+               zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh4");
                return;
        }
        if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) {
                dev_err(&adapter->ccw_device->dev,
                        "The FCP adapter only supports older "
                        "control block versions\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh5", req);
+               zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh5");
        }
 }
 
@@ -700,7 +700,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
                del_timer(&req->timer);
                /* lookup request again, list might have changed */
                zfcp_reqlist_find_rm(adapter->req_list, req_id);
-               zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1", req);
+               zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1");
                return -EIO;
        }
 
@@ -754,10 +754,11 @@ int zfcp_fsf_status_read(struct zfcp_qdio *qdio)
        goto out;
 
 failed_req_send:
+       req->data = NULL;
        mempool_free(sr_buf, adapter->pool.status_read_data);
 failed_buf:
+       zfcp_dbf_hba_fsf_uss("fssr__1", req);
        zfcp_fsf_req_free(req);
-       zfcp_dbf_hba_fsf_unsol("fail", adapter->dbf, NULL);
 out:
        spin_unlock_irq(&qdio->req_q_lock);
        return retval;
@@ -776,14 +777,13 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
        case FSF_PORT_HANDLE_NOT_VALID:
                if (fsq->word[0] == fsq->word[1]) {
                        zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0,
-                                               "fsafch1", req);
+                                               "fsafch1");
                        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                }
                break;
        case FSF_LUN_HANDLE_NOT_VALID:
                if (fsq->word[0] == fsq->word[1]) {
-                       zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fsafch2",
-                                            req);
+                       zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fsafch2");
                        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                }
                break;
@@ -794,14 +794,13 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
                zfcp_erp_set_port_status(zfcp_sdev->port,
                                         ZFCP_STATUS_COMMON_ACCESS_BOXED);
                zfcp_erp_port_reopen(zfcp_sdev->port,
-                                    ZFCP_STATUS_COMMON_ERP_FAILED, "fsafch3",
-                                    req);
+                                    ZFCP_STATUS_COMMON_ERP_FAILED, "fsafch3");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_LUN_BOXED:
                zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ACCESS_BOXED);
                zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
-                                   "fsafch4", req);
+                                   "fsafch4");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                 break;
        case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -851,7 +850,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
 
        zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
 
-       req->data = zfcp_sdev;
+       req->data = sdev;
        req->handler = zfcp_fsf_abort_fcp_command_handler;
        req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
        req->qtcb->header.port_handle = zfcp_sdev->port->handle;
@@ -882,7 +881,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
 
        switch (header->fsf_status) {
         case FSF_GOOD:
-               zfcp_dbf_san_ct_response(req);
+               zfcp_dbf_san_res("fsscth1", req);
                ct->status = 0;
                break;
         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -902,7 +901,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_PORT_HANDLE_NOT_VALID:
-               zfcp_erp_adapter_reopen(adapter, 0, "fsscth1", req);
+               zfcp_erp_adapter_reopen(adapter, 0, "fsscth1");
                /* fall through */
        case FSF_GENERIC_COMMAND_REJECTED:
        case FSF_PAYLOAD_SIZE_MISMATCH:
@@ -1025,7 +1024,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
        req->qtcb->header.port_handle = wka_port->handle;
        req->data = ct;
 
-       zfcp_dbf_san_ct_request(req, wka_port->d_id);
+       zfcp_dbf_san_req("fssct_1", req, wka_port->d_id);
 
        ret = zfcp_fsf_req_send(req);
        if (ret)
@@ -1053,7 +1052,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
 
        switch (header->fsf_status) {
        case FSF_GOOD:
-               zfcp_dbf_san_els_response(req);
+               zfcp_dbf_san_res("fsselh1", req);
                send_els->status = 0;
                break;
        case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -1127,7 +1126,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
        req->handler = zfcp_fsf_send_els_handler;
        req->data = els;
 
-       zfcp_dbf_san_els_request(req);
+       zfcp_dbf_san_req("fssels1", req, d_id);
 
        ret = zfcp_fsf_req_send(req);
        if (ret)
@@ -1448,7 +1447,7 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req)
 
        switch (req->qtcb->header.fsf_status) {
        case FSF_PORT_HANDLE_NOT_VALID:
-               zfcp_erp_adapter_reopen(port->adapter, 0, "fscph_1", req);
+               zfcp_erp_adapter_reopen(port->adapter, 0, "fscph_1");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -1580,7 +1579,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
 
        if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-               zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1", req);
+               zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1");
        }
 
        wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
@@ -1638,7 +1637,7 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
 
        switch (header->fsf_status) {
        case FSF_PORT_HANDLE_NOT_VALID:
-               zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1", req);
+               zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_ACCESS_DENIED:
@@ -1654,7 +1653,7 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
                                                  &sdev_to_zfcp(sdev)->status);
                zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ACCESS_BOXED);
                zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
-                                    "fscpph2", req);
+                                    "fscpph2");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -1743,7 +1742,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req)
        switch (header->fsf_status) {
 
        case FSF_PORT_HANDLE_NOT_VALID:
-               zfcp_erp_adapter_reopen(adapter, 0, "fsouh_1", req);
+               zfcp_erp_adapter_reopen(adapter, 0, "fsouh_1");
                /* fall through */
        case FSF_LUN_ALREADY_OPEN:
                break;
@@ -1755,8 +1754,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req)
                zfcp_erp_set_port_status(zfcp_sdev->port,
                                         ZFCP_STATUS_COMMON_ACCESS_BOXED);
                zfcp_erp_port_reopen(zfcp_sdev->port,
-                                    ZFCP_STATUS_COMMON_ERP_FAILED, "fsouh_2",
-                                    req);
+                                    ZFCP_STATUS_COMMON_ERP_FAILED, "fsouh_2");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_LUN_SHARING_VIOLATION:
@@ -1852,20 +1850,18 @@ static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req)
 
        switch (req->qtcb->header.fsf_status) {
        case FSF_PORT_HANDLE_NOT_VALID:
-               zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1",
-                                       req);
+               zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_LUN_HANDLE_NOT_VALID:
-               zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fscuh_2", req);
+               zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fscuh_2");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_PORT_BOXED:
                zfcp_erp_set_port_status(zfcp_sdev->port,
                                         ZFCP_STATUS_COMMON_ACCESS_BOXED);
                zfcp_erp_port_reopen(zfcp_sdev->port,
-                                    ZFCP_STATUS_COMMON_ERP_FAILED, "fscuh_3",
-                                    req);
+                                    ZFCP_STATUS_COMMON_ERP_FAILED, "fscuh_3");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -2002,13 +1998,12 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
        switch (header->fsf_status) {
        case FSF_HANDLE_MISMATCH:
        case FSF_PORT_HANDLE_NOT_VALID:
-               zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fssfch1",
-                                       req);
+               zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fssfch1");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_FCPLUN_NOT_VALID:
        case FSF_LUN_HANDLE_NOT_VALID:
-               zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fssfch2", req);
+               zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fssfch2");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -2026,7 +2021,7 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
                        (unsigned long long)zfcp_scsi_dev_lun(sdev),
                        (unsigned long long)zfcp_sdev->port->wwpn);
                zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0,
-                                         "fssfch3", req);
+                                         "fssfch3");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_CMND_LENGTH_NOT_VALID:
@@ -2037,21 +2032,20 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
                        (unsigned long long)zfcp_scsi_dev_lun(sdev),
                        (unsigned long long)zfcp_sdev->port->wwpn);
                zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0,
-                                         "fssfch4", req);
+                                         "fssfch4");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_PORT_BOXED:
                zfcp_erp_set_port_status(zfcp_sdev->port,
                                         ZFCP_STATUS_COMMON_ACCESS_BOXED);
                zfcp_erp_port_reopen(zfcp_sdev->port,
-                                    ZFCP_STATUS_COMMON_ERP_FAILED, "fssfch5",
-                                    req);
+                                    ZFCP_STATUS_COMMON_ERP_FAILED, "fssfch5");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_LUN_BOXED:
                zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ACCESS_BOXED);
                zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
-                                   "fssfch6", req);
+                                   "fssfch6");
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -2069,8 +2063,6 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
        struct fcp_resp_with_ext *fcp_rsp;
        unsigned long flags;
 
-       zfcp_fsf_fcp_handler_common(req);
-
        read_lock_irqsave(&req->adapter->abort_lock, flags);
 
        scpnt = req->data;
@@ -2079,6 +2071,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
                return;
        }
 
+       zfcp_fsf_fcp_handler_common(req);
+
        if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
                set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
                goto skip_fsfstatus;
@@ -2104,7 +2098,7 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
 
 skip_fsfstatus:
        zfcp_fsf_req_trace(req, scpnt);
-       zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
+       zfcp_dbf_scsi_result(scpnt, req);
 
        scpnt->host_scribble = NULL;
        (scpnt->scsi_done) (scpnt);
@@ -2170,12 +2164,13 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
        struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
        struct zfcp_qdio *qdio = adapter->qdio;
        struct fsf_qtcb_bottom_io *io;
+       unsigned long flags;
 
        if (unlikely(!(atomic_read(&zfcp_sdev->status) &
                       ZFCP_STATUS_COMMON_UNBLOCKED)))
                return -EBUSY;
 
-       spin_lock(&qdio->req_q_lock);
+       spin_lock_irqsave(&qdio->req_q_lock, flags);
        if (atomic_read(&qdio->req_q_free) <= 0) {
                atomic_inc(&qdio->req_q_full);
                goto out;
@@ -2239,7 +2234,7 @@ failed_scsi_cmnd:
        zfcp_fsf_req_free(req);
        scsi_cmnd->host_scribble = NULL;
 out:
-       spin_unlock(&qdio->req_q_lock);
+       spin_unlock_irqrestore(&qdio->req_q_lock, flags);
        return retval;
 }
 
@@ -2419,3 +2414,12 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
                        break;
        }
 }
+
+struct zfcp_fsf_req *zfcp_fsf_get_req(struct zfcp_qdio *qdio,
+                                     struct qdio_buffer *sbal)
+{
+       struct qdio_buffer_element *sbale = &sbal->element[0];
+       u64 req_id = (unsigned long) sbale->addr;
+
+       return zfcp_reqlist_find(qdio->adapter->req_list, req_id);
+}
index a0554beb4179efde170b463689f53b1fbf637290..2511f92302dd55803b03370af11bc291316ef097 100644 (file)
@@ -41,7 +41,7 @@ static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
                zfcp_qdio_siosl(adapter);
        zfcp_erp_adapter_reopen(adapter,
                                ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
-                               ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL);
+                               ZFCP_STATUS_COMMON_ERP_FAILED, id);
 }
 
 static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
@@ -74,7 +74,6 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
        struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
 
        if (unlikely(qdio_err)) {
-               zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
                zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err);
                return;
        }
@@ -97,7 +96,6 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
        int sbal_idx, sbal_no;
 
        if (unlikely(qdio_err)) {
-               zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
                zfcp_qdio_handler_error(qdio, "qdires1", qdio_err);
                return;
        }
@@ -116,7 +114,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
         * put SBALs back to response queue
         */
        if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count))
-               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2", NULL);
+               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2");
 }
 
 static struct qdio_buffer_element *
@@ -236,7 +234,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
        if (!ret) {
                atomic_inc(&qdio->req_q_full);
                /* assume hanging outbound queue, try queue recovery */
-               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1", NULL);
+               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1");
        }
 
        spin_lock_irq(&qdio->req_q_lock);
@@ -309,6 +307,7 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
                return -ENOMEM;
 
        zfcp_qdio_setup_init_data(&init_data, qdio);
+       init_waitqueue_head(&qdio->req_q_wq);
 
        return qdio_allocate(&init_data);
 }
@@ -393,6 +392,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
        /* set index of first avalable SBALS / number of available SBALS */
        qdio->req_q_idx = 0;
        atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q);
+       atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
 
        return 0;
 
index 50286d8707f305b981c1e56ffa02df7b3ce3b0d9..ddb5800823a92895e63b4a6a4ee7942a5239317e 100644 (file)
@@ -30,6 +30,10 @@ module_param_named(dif, enable_dif, bool, 0600);
 MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support");
 #endif
 
+static bool allow_lun_scan = 1;
+module_param(allow_lun_scan, bool, 0600);
+MODULE_PARM_DESC(allow_lun_scan, "For NPIV, scan and attach all storage LUNs");
+
 static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
                                        int reason)
 {
@@ -68,31 +72,26 @@ static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
 
 static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
 {
-       struct zfcp_adapter *adapter =
-               (struct zfcp_adapter *) scpnt->device->host->hostdata[0];
-
        set_host_byte(scpnt, result);
-       zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt);
+       zfcp_dbf_scsi_fail_send(scpnt);
        scpnt->scsi_done(scpnt);
 }
 
-static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
-                                 void (*done) (struct scsi_cmnd *))
+static
+int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt)
 {
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
-       struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
        struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device));
        int    status, scsi_result, ret;
 
        /* reset the status for this request */
        scpnt->result = 0;
        scpnt->host_scribble = NULL;
-       scpnt->scsi_done = done;
 
        scsi_result = fc_remote_port_chkready(rport);
        if (unlikely(scsi_result)) {
                scpnt->result = scsi_result;
-               zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt);
+               zfcp_dbf_scsi_fail_send(scpnt);
                scpnt->scsi_done(scpnt);
                return 0;
        }
@@ -135,6 +134,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
        struct zfcp_port *port;
        struct zfcp_unit *unit;
+       int npiv = adapter->connection_features & FSF_FEATURE_NPIV_MODE;
 
        port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
        if (!port)
@@ -144,7 +144,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
        if (unit)
                put_device(&unit->dev);
 
-       if (!unit && !(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) {
+       if (!unit && !(allow_lun_scan && npiv)) {
                put_device(&port->dev);
                return -ENXIO;
        }
@@ -159,7 +159,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
        spin_lock_init(&zfcp_sdev->latencies.lock);
 
        zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
-       zfcp_erp_lun_reopen(sdev, 0, "scsla_1", NULL);
+       zfcp_erp_lun_reopen(sdev, 0, "scsla_1");
        zfcp_erp_wait(port->adapter);
 
        return 0;
@@ -183,8 +183,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
        old_req = zfcp_reqlist_find(adapter->req_list, old_reqid);
        if (!old_req) {
                write_unlock_irqrestore(&adapter->abort_lock, flags);
-               zfcp_dbf_scsi_abort("lte1", adapter->dbf, scpnt, NULL,
-                                   old_reqid);
+               zfcp_dbf_scsi_abort("abrt_or", scpnt, NULL);
                return FAILED; /* completion could be in progress */
        }
        old_req->data = NULL;
@@ -199,29 +198,32 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 
                zfcp_erp_wait(adapter);
                ret = fc_block_scsi_eh(scpnt);
-               if (ret)
+               if (ret) {
+                       zfcp_dbf_scsi_abort("abrt_bl", scpnt, NULL);
                        return ret;
+               }
                if (!(atomic_read(&adapter->status) &
                      ZFCP_STATUS_COMMON_RUNNING)) {
-                       zfcp_dbf_scsi_abort("nres", adapter->dbf, scpnt, NULL,
-                                           old_reqid);
+                       zfcp_dbf_scsi_abort("abrt_ru", scpnt, NULL);
                        return SUCCESS;
                }
        }
-       if (!abrt_req)
+       if (!abrt_req) {
+               zfcp_dbf_scsi_abort("abrt_ar", scpnt, NULL);
                return FAILED;
+       }
 
        wait_for_completion(&abrt_req->completion);
 
        if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED)
-               dbf_tag = "okay";
+               dbf_tag = "abrt_ok";
        else if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED)
-               dbf_tag = "lte2";
+               dbf_tag = "abrt_nn";
        else {
-               dbf_tag = "fail";
+               dbf_tag = "abrt_fa";
                retval = FAILED;
        }
-       zfcp_dbf_scsi_abort(dbf_tag, adapter->dbf, scpnt, abrt_req, old_reqid);
+       zfcp_dbf_scsi_abort(dbf_tag, scpnt, abrt_req);
        zfcp_fsf_req_free(abrt_req);
        return retval;
 }
@@ -281,7 +283,7 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
        struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
        int ret;
 
-       zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt);
+       zfcp_erp_adapter_reopen(adapter, 0, "schrh_1");
        zfcp_erp_wait(adapter);
        ret = fc_block_scsi_eh(scpnt);
        if (ret)
@@ -519,7 +521,7 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
        port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
 
        if (port) {
-               zfcp_erp_port_forced_reopen(port, 0, "sctrpi1", NULL);
+               zfcp_erp_port_forced_reopen(port, 0, "sctrpi1");
                put_device(&port->dev);
        }
 }
index 2f2c54f4718f40f0e49b04315678a56a1aa866e8..cdc4ff78a7baf787e36958b84c208654d97fa9c1 100644 (file)
@@ -105,8 +105,7 @@ static ssize_t zfcp_sysfs_port_failed_store(struct device *dev,
                return -EINVAL;
 
        zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_RUNNING);
-       zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2",
-                            NULL);
+       zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2");
        zfcp_erp_wait(port->adapter);
 
        return count;
@@ -148,7 +147,7 @@ static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev,
        if (sdev) {
                zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
                zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
-                                   "syufai2", NULL);
+                                   "syufai2");
                zfcp_erp_wait(unit->port->adapter);
        } else
                zfcp_unit_scsi_scan(unit);
@@ -198,7 +197,7 @@ static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev,
 
        zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
        zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
-                               "syafai2", NULL);
+                               "syafai2");
        zfcp_erp_wait(adapter);
 out:
        zfcp_ccw_adapter_put(adapter);
@@ -256,7 +255,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
 
        put_device(&port->dev);
 
-       zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL);
+       zfcp_erp_port_shutdown(port, 0, "syprs_1");
        zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
  out:
        zfcp_ccw_adapter_put(adapter);
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 d2eefd3e3bd5eb1f0ca69113bd336b9c33791fd1..ed26a6a97a44f680d3e4cc8adc49f3c5913cc49b 100644 (file)
@@ -3,6 +3,6 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
 bfa-y := bfad.o bfad_im.o bfad_attr.o bfad_debugfs.o
 bfa-y += bfa_ioc.o bfa_ioc_cb.o bfa_ioc_ct.o bfa_hw_cb.o bfa_hw_ct.o
 bfa-y += bfa_fcs.o bfa_fcs_lport.o bfa_fcs_rport.o bfa_fcs_fcpim.o bfa_fcbuild.o
-bfa-y += bfa_port.o bfa_fcpim.o bfa_core.o bfa_drv.o bfa_svc.o
+bfa-y += bfa_port.o bfa_fcpim.o bfa_core.o bfa_svc.o
 
 ccflags-y := -DBFA_PERF_BUILD
index ff2bd07161f746a1c3dee089807628b6fe90a840..cabc6b92b25d47e95047944bd48ffa1143dc6c65 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef __BFA_H__
 #define __BFA_H__
 
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 #include "bfa_cs.h"
 #include "bfa_plog.h"
 #include "bfa_defs_svc.h"
@@ -33,7 +33,6 @@ typedef void    (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
  * Interrupt message handlers
  */
 void bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m);
-void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
 
 /*
  * Request and response queue related defines
@@ -297,7 +296,6 @@ void bfa_iocfc_attach(struct bfa_s *bfa, void *bfad,
                      struct bfa_iocfc_cfg_s *cfg,
                      struct bfa_meminfo_s *meminfo,
                      struct bfa_pcidev_s *pcidev);
-void bfa_iocfc_detach(struct bfa_s *bfa);
 void bfa_iocfc_init(struct bfa_s *bfa);
 void bfa_iocfc_start(struct bfa_s *bfa);
 void bfa_iocfc_stop(struct bfa_s *bfa);
@@ -333,7 +331,6 @@ void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, u32 *nvecs,
                           u32 *maxvec);
 void bfa_hwct_msix_get_rme_range(struct bfa_s *bfa, u32 *start,
                                 u32 *end);
-void bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi);
 void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns);
 wwn_t bfa_iocfc_get_pwwn(struct bfa_s *bfa);
 wwn_t bfa_iocfc_get_nwwn(struct bfa_s *bfa);
@@ -386,19 +383,11 @@ void bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg,
 void bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
                struct bfa_meminfo_s *meminfo,
                struct bfa_pcidev_s *pcidev);
-void bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod);
-void bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog);
 void bfa_detach(struct bfa_s *bfa);
-void bfa_init(struct bfa_s *bfa);
-void bfa_start(struct bfa_s *bfa);
-void bfa_stop(struct bfa_s *bfa);
-void bfa_attach_fcs(struct bfa_s *bfa);
 void bfa_cb_init(void *bfad, bfa_status_t status);
 void bfa_cb_updateq(void *bfad, bfa_status_t status);
 
 bfa_boolean_t bfa_intx(struct bfa_s *bfa);
-void bfa_intx_disable(struct bfa_s *bfa);
-void bfa_intx_enable(struct bfa_s *bfa);
 void bfa_isr_enable(struct bfa_s *bfa);
 void bfa_isr_disable(struct bfa_s *bfa);
 
@@ -408,31 +397,14 @@ void bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q);
 
 typedef void (*bfa_cb_ioc_t) (void *cbarg, enum bfa_status status);
 void bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr);
-void bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr);
 
-void bfa_adapter_get_attr(struct bfa_s *bfa,
-                         struct bfa_adapter_attr_s *ad_attr);
-u64 bfa_adapter_get_id(struct bfa_s *bfa);
 
 bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
                                   struct bfa_iocfc_intr_attr_s *attr);
 
 void bfa_iocfc_enable(struct bfa_s *bfa);
 void bfa_iocfc_disable(struct bfa_s *bfa);
-void bfa_chip_reset(struct bfa_s *bfa);
-void bfa_timer_tick(struct bfa_s *bfa);
 #define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout)                \
        bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout)
 
-/*
- * BFA debug API functions
- */
-bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen);
-bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen);
-bfa_status_t bfa_debug_fwcore(struct bfa_s *bfa, void *buf,
-                             u32 *offset, int *buflen);
-void bfa_debug_fwsave_clear(struct bfa_s *bfa);
-bfa_status_t bfa_fw_stats_get(struct bfa_s *bfa, void *data);
-bfa_status_t bfa_fw_stats_clear(struct bfa_s *bfa);
-
 #endif /* __BFA_H__ */
diff --git a/drivers/scsi/bfa/bfa_cb_ioim.h b/drivers/scsi/bfa/bfa_cb_ioim.h
deleted file mode 100644 (file)
index 6f02101..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-
-#ifndef __BFA_HCB_IOIM_H__
-#define __BFA_HCB_IOIM_H__
-
-#include "bfa_os_inc.h"
-/*
- * task attribute values in FCP-2 FCP_CMND IU
- */
-#define SIMPLE_Q    0
-#define HEAD_OF_Q   1
-#define ORDERED_Q   2
-#define ACA_Q      4
-#define UNTAGGED    5
-
-static inline lun_t
-bfad_int_to_lun(u32 luno)
-{
-       union {
-               u16     scsi_lun[4];
-               lun_t           bfa_lun;
-       } lun;
-
-       lun.bfa_lun     = 0;
-       lun.scsi_lun[0] = cpu_to_be16(luno);
-
-       return lun.bfa_lun;
-}
-
-/*
- * Get LUN for the I/O request
- */
-#define bfa_cb_ioim_get_lun(__dio)     \
-       bfad_int_to_lun(((struct scsi_cmnd *)__dio)->device->lun)
-
-/*
- * Get CDB for the I/O request
- */
-static inline u8 *
-bfa_cb_ioim_get_cdb(struct bfad_ioim_s *dio)
-{
-       struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-
-       return (u8 *) cmnd->cmnd;
-}
-
-/*
- * Get I/O direction (read/write) for the I/O request
- */
-static inline enum fcp_iodir
-bfa_cb_ioim_get_iodir(struct bfad_ioim_s *dio)
-{
-       struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-       enum dma_data_direction dmadir;
-
-       dmadir = cmnd->sc_data_direction;
-       if (dmadir == DMA_TO_DEVICE)
-               return FCP_IODIR_WRITE;
-       else if (dmadir == DMA_FROM_DEVICE)
-               return FCP_IODIR_READ;
-       else
-               return FCP_IODIR_NONE;
-}
-
-/*
- * Get IO size in bytes for the I/O request
- */
-static inline u32
-bfa_cb_ioim_get_size(struct bfad_ioim_s *dio)
-{
-       struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-
-       return scsi_bufflen(cmnd);
-}
-
-/*
- * Get timeout for the I/O request
- */
-static inline u8
-bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio)
-{
-       struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-       /*
-        * TBD: need a timeout for scsi passthru
-        */
-       if (cmnd->device->host == NULL)
-               return 4;
-
-       return 0;
-}
-
-/*
- * Get Command Reference Number for the I/O request. 0 if none.
- */
-static inline u8
-bfa_cb_ioim_get_crn(struct bfad_ioim_s *dio)
-{
-       return 0;
-}
-
-/*
- * Get SAM-3 priority for the I/O request. 0 is default.
- */
-static inline u8
-bfa_cb_ioim_get_priority(struct bfad_ioim_s *dio)
-{
-       return 0;
-}
-
-/*
- * Get task attributes for the I/O request. Default is FCP_TASK_ATTR_SIMPLE(0).
- */
-static inline u8
-bfa_cb_ioim_get_taskattr(struct bfad_ioim_s *dio)
-{
-       struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-       u8      task_attr = UNTAGGED;
-
-       if (cmnd->device->tagged_supported) {
-               switch (cmnd->tag) {
-               case HEAD_OF_QUEUE_TAG:
-                       task_attr = HEAD_OF_Q;
-                       break;
-               case ORDERED_QUEUE_TAG:
-                       task_attr = ORDERED_Q;
-                       break;
-               default:
-                       task_attr = SIMPLE_Q;
-                       break;
-               }
-       }
-
-       return task_attr;
-}
-
-/*
- * Get CDB length in bytes for the I/O request. Default is FCP_CMND_CDB_LEN(16).
- */
-static inline u8
-bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
-{
-       struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
-
-       return cmnd->cmd_len;
-}
-
-/*
- * Assign queue to be used for the I/O request. This value depends on whether
- * the driver wants to use the queues via any specific algorithm. Currently,
- * this is not supported.
- */
-#define bfa_cb_ioim_get_reqq(__dio) BFA_FALSE
-
-#endif /* __BFA_HCB_IOIM_H__ */
index 2345f48dc57fc9a3940665d75b11a3a205f22b16..3f7f3742e72c2228cbc44bbedd6d5e3335dcfdba 100644 (file)
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_modules.h"
 #include "bfi_ctreg.h"
-#include "bfad_drv.h"
 
 BFA_TRC_FILE(HAL, CORE);
 
+/*
+ * BFA module list terminated by NULL
+ */
+static struct bfa_module_s *hal_mods[] = {
+       &hal_mod_sgpg,
+       &hal_mod_fcport,
+       &hal_mod_fcxp,
+       &hal_mod_lps,
+       &hal_mod_uf,
+       &hal_mod_rport,
+       &hal_mod_fcpim,
+       NULL
+};
+
+/*
+ * Message handlers for various modules.
+ */
+static bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
+       bfa_isr_unhandled,      /* NONE */
+       bfa_isr_unhandled,      /* BFI_MC_IOC */
+       bfa_isr_unhandled,      /* BFI_MC_DIAG */
+       bfa_isr_unhandled,      /* BFI_MC_FLASH */
+       bfa_isr_unhandled,      /* BFI_MC_CEE */
+       bfa_fcport_isr,         /* BFI_MC_FCPORT */
+       bfa_isr_unhandled,      /* BFI_MC_IOCFC */
+       bfa_isr_unhandled,      /* BFI_MC_LL */
+       bfa_uf_isr,             /* BFI_MC_UF */
+       bfa_fcxp_isr,           /* BFI_MC_FCXP */
+       bfa_lps_isr,            /* BFI_MC_LPS */
+       bfa_rport_isr,          /* BFI_MC_RPORT */
+       bfa_itnim_isr,          /* BFI_MC_ITNIM */
+       bfa_isr_unhandled,      /* BFI_MC_IOIM_READ */
+       bfa_isr_unhandled,      /* BFI_MC_IOIM_WRITE */
+       bfa_isr_unhandled,      /* BFI_MC_IOIM_IO */
+       bfa_ioim_isr,           /* BFI_MC_IOIM */
+       bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */
+       bfa_tskim_isr,          /* BFI_MC_TSKIM */
+       bfa_isr_unhandled,      /* BFI_MC_SBOOT */
+       bfa_isr_unhandled,      /* BFI_MC_IPFC */
+       bfa_isr_unhandled,      /* BFI_MC_PORT */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+       bfa_isr_unhandled,      /* --------- */
+};
+/*
+ * Message handlers for mailbox command classes
+ */
+static bfa_ioc_mbox_mcfunc_t  bfa_mbox_isrs[BFI_MC_MAX] = {
+       NULL,
+       NULL,           /* BFI_MC_IOC   */
+       NULL,           /* BFI_MC_DIAG  */
+       NULL,           /* BFI_MC_FLASH */
+       NULL,           /* BFI_MC_CEE   */
+       NULL,           /* BFI_MC_PORT  */
+       bfa_iocfc_isr,  /* BFI_MC_IOCFC */
+       NULL,
+};
+
+
+
+static void
+bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi)
+{
+       struct bfa_port_s       *port = &bfa->modules.port;
+       u32                     dm_len;
+       u8                      *dm_kva;
+       u64                     dm_pa;
+
+       dm_len = bfa_port_meminfo();
+       dm_kva = bfa_meminfo_dma_virt(mi);
+       dm_pa  = bfa_meminfo_dma_phys(mi);
+
+       memset(port, 0, sizeof(struct bfa_port_s));
+       bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod);
+       bfa_port_mem_claim(port, dm_kva, dm_pa);
+
+       bfa_meminfo_dma_virt(mi) = dm_kva + dm_len;
+       bfa_meminfo_dma_phys(mi) = dm_pa + dm_len;
+}
+
 /*
  * BFA IOC FC related definitions
  */
@@ -66,18 +153,6 @@ static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;
 /*
  * BFA Interrupt handling functions
  */
-static void
-bfa_msix_errint(struct bfa_s *bfa, u32 intr)
-{
-       bfa_ioc_error_isr(&bfa->ioc);
-}
-
-static void
-bfa_msix_lpu(struct bfa_s *bfa)
-{
-       bfa_ioc_mbox_isr(&bfa->ioc);
-}
-
 static void
 bfa_reqq_resume(struct bfa_s *bfa, int qid)
 {
@@ -104,9 +179,6 @@ bfa_msix_all(struct bfa_s *bfa, int vec)
        bfa_intx(bfa);
 }
 
-/*
- *  hal_intr_api
- */
 bfa_boolean_t
 bfa_intx(struct bfa_s *bfa)
 {
@@ -150,18 +222,6 @@ bfa_intx(struct bfa_s *bfa)
        return BFA_TRUE;
 }
 
-void
-bfa_intx_enable(struct bfa_s *bfa)
-{
-       writel(bfa->iocfc.intr_mask, bfa->iocfc.bfa_regs.intr_mask);
-}
-
-void
-bfa_intx_disable(struct bfa_s *bfa)
-{
-       writel(-1L, bfa->iocfc.bfa_regs.intr_mask);
-}
-
 void
 bfa_isr_enable(struct bfa_s *bfa)
 {
@@ -282,7 +342,7 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
        intr = readl(bfa->iocfc.bfa_regs.intr_status);
 
        if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
-               bfa_msix_lpu(bfa);
+               bfa_ioc_mbox_isr(&bfa->ioc);
 
        intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
                __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
@@ -313,22 +373,16 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
                }
 
                writel(intr, bfa->iocfc.bfa_regs.intr_status);
-               bfa_msix_errint(bfa, intr);
+               bfa_ioc_error_isr(&bfa->ioc);
        }
 }
 
-void
-bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func)
-{
-       bfa_isrs[mc] = isr_func;
-}
-
 /*
  * BFA IOC FC related functions
  */
 
 /*
- *  hal_ioc_pvt BFA IOC private functions
+ *  BFA IOC private functions
  */
 
 static void
@@ -488,8 +542,8 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
         * First allocate dma memory for IOC.
         */
        bfa_ioc_mem_claim(&bfa->ioc, dm_kva, dm_pa);
-       dm_kva += bfa_ioc_meminfo();
-       dm_pa  += bfa_ioc_meminfo();
+       dm_kva += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
+       dm_pa  += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
 
        /*
         * Claim DMA-able memory for the request/response queues and for shadow
@@ -552,7 +606,7 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
        bfa_meminfo_dma_virt(meminfo) = dm_kva;
        bfa_meminfo_dma_phys(meminfo) = dm_pa;
 
-       dbgsz = bfa_ioc_debug_trcsz(bfa_auto_recover);
+       dbgsz = (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
        if (dbgsz > 0) {
                bfa_ioc_debug_memclaim(&bfa->ioc, bfa_meminfo_kva(meminfo));
                bfa_meminfo_kva(meminfo) += dbgsz;
@@ -735,9 +789,6 @@ bfa_iocfc_reset_cbfn(void *bfa_arg)
        bfa_isr_enable(bfa);
 }
 
-/*
- *  hal_ioc_public
- */
 
 /*
  * Query IOC memory requirement information.
@@ -747,11 +798,11 @@ bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
                  u32 *dm_len)
 {
        /* dma memory for IOC */
-       *dm_len += bfa_ioc_meminfo();
+       *dm_len += BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
 
        bfa_iocfc_fw_cfg_sz(cfg, dm_len);
        bfa_iocfc_cqs_sz(cfg, dm_len);
-       *km_len += bfa_ioc_debug_trcsz(bfa_auto_recover);
+       *km_len += (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
 }
 
 /*
@@ -783,22 +834,13 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 
        bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
        bfa_iocfc_mem_claim(bfa, cfg, meminfo);
-       bfa_timer_init(&bfa->timer_mod);
+       INIT_LIST_HEAD(&bfa->timer_mod.timer_q);
 
        INIT_LIST_HEAD(&bfa->comp_q);
        for (i = 0; i < BFI_IOC_MAX_CQS; i++)
                INIT_LIST_HEAD(&bfa->reqq_waitq[i]);
 }
 
-/*
- * Query IOC memory requirement information.
- */
-void
-bfa_iocfc_detach(struct bfa_s *bfa)
-{
-       bfa_ioc_detach(&bfa->ioc);
-}
-
 /*
  * Query IOC memory requirement information.
  */
@@ -856,18 +898,6 @@ bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
        }
 }
 
-void
-bfa_adapter_get_attr(struct bfa_s *bfa, struct bfa_adapter_attr_s *ad_attr)
-{
-       bfa_ioc_get_adapter_attr(&bfa->ioc, ad_attr);
-}
-
-u64
-bfa_adapter_get_id(struct bfa_s *bfa)
-{
-       return bfa_ioc_get_adid(&bfa->ioc);
-}
-
 void
 bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
 {
@@ -998,9 +1028,6 @@ bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
        return cfgrsp->pbc_cfg.nvports;
 }
 
-/*
- *  hal_api
- */
 
 /*
  * Use this function query the memory requirement of the BFA library.
@@ -1129,79 +1156,7 @@ bfa_detach(struct bfa_s *bfa)
 
        for (i = 0; hal_mods[i]; i++)
                hal_mods[i]->detach(bfa);
-
-       bfa_iocfc_detach(bfa);
-}
-
-
-void
-bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod)
-{
-       bfa->trcmod = trcmod;
-}
-
-void
-bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog)
-{
-       bfa->plog = plog;
-}
-
-/*
- * Initialize IOC.
- *
- * This function will return immediately, when the IOC initialization is
- * completed, the bfa_cb_init() will be called.
- *
- * @param[in]  bfa     instance
- *
- * @return void
- *
- * Special Considerations:
- *
- * @note
- * When this function returns, the driver should register the interrupt service
- * routine(s) and enable the device interrupts. If this is not done,
- * bfa_cb_init() will never get called
- */
-void
-bfa_init(struct bfa_s *bfa)
-{
-       bfa_iocfc_init(bfa);
-}
-
-/*
- * Use this function initiate the IOC configuration setup. This function
- * will return immediately.
- *
- * @param[in]  bfa     instance
- *
- * @return None
- */
-void
-bfa_start(struct bfa_s *bfa)
-{
-       bfa_iocfc_start(bfa);
-}
-
-/*
- * Use this function quiese the IOC. This function will return immediately,
- * when the IOC is actually stopped, the bfad->comp will be set.
- *
- * @param[in]bfa - pointer to bfa_t.
- *
- * @return None
- *
- * Special Considerations:
- * bfad->comp can be set before or after bfa_stop() returns.
- *
- * @note
- * In case of any failure, we could handle it automatically by doing a
- * reset and then succeed the bfa_stop() call.
- */
-void
-bfa_stop(struct bfa_s *bfa)
-{
-       bfa_iocfc_stop(bfa);
+       bfa_ioc_detach(&bfa->ioc);
 }
 
 void
@@ -1237,20 +1192,6 @@ bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
        }
 }
 
-void
-bfa_attach_fcs(struct bfa_s *bfa)
-{
-       bfa->fcs = BFA_TRUE;
-}
-
-/*
- * Periodic timer heart beat from driver
- */
-void
-bfa_timer_tick(struct bfa_s *bfa)
-{
-       bfa_timer_beat(&bfa->timer_mod);
-}
 
 /*
  * Return the list of PCI vendor/device id lists supported by this
@@ -1321,89 +1262,3 @@ bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
        cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
        cfg->drvcfg.min_cfg        = BFA_TRUE;
 }
-
-void
-bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr)
-{
-       bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
-}
-
-/*
- * Retrieve firmware trace information on IOC failure.
- */
-bfa_status_t
-bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
-{
-       return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
-}
-
-/*
- * Clear the saved firmware trace information of an IOC.
- */
-void
-bfa_debug_fwsave_clear(struct bfa_s *bfa)
-{
-       bfa_ioc_debug_fwsave_clear(&bfa->ioc);
-}
-
-/*
- * Fetch firmware trace data.
- *
- * @param[in]          bfa                     BFA instance
- * @param[out]         trcdata         Firmware trace buffer
- * @param[in,out]      trclen          Firmware trace buffer len
- *
- * @retval BFA_STATUS_OK                       Firmware trace is fetched.
- * @retval BFA_STATUS_INPROGRESS       Firmware trace fetch is in progress.
- */
-bfa_status_t
-bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
-{
-       return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
-}
-
-/*
- * Dump firmware memory.
- *
- * @param[in]          bfa             BFA instance
- * @param[out]         buf             buffer for dump
- * @param[in,out]      offset          smem offset to start read
- * @param[in,out]      buflen          length of buffer
- *
- * @retval BFA_STATUS_OK               Firmware memory is dumped.
- * @retval BFA_STATUS_INPROGRESS       Firmware memory dump is in progress.
- */
-bfa_status_t
-bfa_debug_fwcore(struct bfa_s *bfa, void *buf, u32 *offset, int *buflen)
-{
-       return bfa_ioc_debug_fwcore(&bfa->ioc, buf, offset, buflen);
-}
-/*
- * Reset hw semaphore & usage cnt regs and initialize.
- */
-void
-bfa_chip_reset(struct bfa_s *bfa)
-{
-       bfa_ioc_ownership_reset(&bfa->ioc);
-       bfa_ioc_pll_init(&bfa->ioc);
-}
-
-/*
- * Fetch firmware statistics data.
- *
- * @param[in]          bfa             BFA instance
- * @param[out]         data            Firmware stats buffer
- *
- * @retval BFA_STATUS_OK               Firmware trace is fetched.
- */
-bfa_status_t
-bfa_fw_stats_get(struct bfa_s *bfa, void *data)
-{
-       return bfa_ioc_fw_stats_get(&bfa->ioc, data);
-}
-
-bfa_status_t
-bfa_fw_stats_clear(struct bfa_s *bfa)
-{
-       return bfa_ioc_fw_stats_clear(&bfa->ioc);
-}
index 99f242b9aa3110216fb93915338a86d8c22f7955..493009d880a894790fc006af28b7da1f91ff3b1e 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef __BFA_CS_H__
 #define __BFA_CS_H__
 
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 
 /*
  * BFA TRC
 #define BFA_TRC_MAX    (4 * 1024)
 #endif
 
+#define BFA_TRC_TS(_trcm)                               \
+       ({                                              \
+               struct timeval tv;                      \
+                                                       \
+               do_gettimeofday(&tv);                   \
+               (tv.tv_sec*1000000+tv.tv_usec);         \
+       })
+
 #ifndef BFA_TRC_TS
 #define BFA_TRC_TS(_trcm)      ((_trcm)->ticks++)
 #endif
 
 struct bfa_trc_s {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u16     fileno;
        u16     line;
 #else
@@ -361,4 +369,43 @@ bfa_wc_wait(struct bfa_wc_s *wc)
        bfa_wc_down(wc);
 }
 
+static inline void
+wwn2str(char *wwn_str, u64 wwn)
+{
+       union {
+               u64 wwn;
+               u8 byte[8];
+       } w;
+
+       w.wwn = wwn;
+       sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", w.byte[0],
+               w.byte[1], w.byte[2], w.byte[3], w.byte[4], w.byte[5],
+               w.byte[6], w.byte[7]);
+}
+
+static inline void
+fcid2str(char *fcid_str, u32 fcid)
+{
+       union {
+               u32 fcid;
+               u8 byte[4];
+       } f;
+
+       f.fcid = fcid;
+       sprintf(fcid_str, "%02x:%02x:%02x", f.byte[1], f.byte[2], f.byte[3]);
+}
+
+#define bfa_swap_3b(_x)                                \
+       ((((_x) & 0xff) << 16) |                \
+       ((_x) & 0x00ff00) |                     \
+       (((_x) & 0xff0000) >> 16))
+
+#ifndef __BIG_ENDIAN
+#define bfa_hton3b(_x)  bfa_swap_3b(_x)
+#else
+#define bfa_hton3b(_x)  (_x)
+#endif
+
+#define bfa_ntoh3b(_x)  bfa_hton3b(_x)
+
 #endif /* __BFA_CS_H__ */
index 4b5b9e35abb9889e72824d01f5ddf361817fc7dd..d85f93aea4650b670ecbbe171c303042c04fd8d8 100644 (file)
@@ -19,7 +19,7 @@
 #define __BFA_DEFS_H__
 
 #include "bfa_fc.h"
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 
 #define BFA_MFG_SERIALNUM_SIZE                  11
 #define STRSZ(_n)                               (((_n) + 4) & ~3)
@@ -446,8 +446,8 @@ enum bfa_boot_bootopt {
  * Boot lun information.
  */
 struct bfa_boot_bootlun_s {
-       wwn_t   pwwn;   /*  port wwn of target */
-       lun_t   lun;    /*  64-bit lun */
+       wwn_t   pwwn;           /*  port wwn of target */
+       struct scsi_lun   lun;  /*  64-bit lun */
 };
 #pragma pack()
 
index e24e9f7ca81ff0b68f0b6ea2383f374a73d47165..648c84176722ce108d556ffc4efd4c883ee16b34 100644 (file)
@@ -34,8 +34,8 @@
 struct bfa_iocfc_intr_attr_s {
        u8              coalesce;       /*  enable/disable coalescing */
        u8              rsvd[3];
-       u16     latency;        /*  latency in microseconds   */
-       u16     delay;          /*  delay in microseconds     */
+       __be16  latency;        /*  latency in microseconds   */
+       __be16  delay;          /*  delay in microseconds     */
 };
 
 /*
@@ -743,7 +743,7 @@ struct bfa_port_cfg_s {
        u8       qos_enabled;   /*  qos enabled or not          */
        u8       cfg_hardalpa;  /*  is hard alpa configured     */
        u8       hardalpa;      /*  configured hard alpa        */
-       u16 maxfrsize;  /*  maximum frame size          */
+       __be16   maxfrsize;     /*  maximum frame size          */
        u8       rx_bbcredit;   /*  receive buffer credits      */
        u8       tx_bbcredit;   /*  transmit buffer credits     */
        u8       ratelimit;     /*  ratelimit enabled or not    */
@@ -843,7 +843,7 @@ struct bfa_fcport_fcf_s {
        u8       fka_disabled;   /*  FKA is disabled      */
        u8       maxsz_verified; /*  FCoE max size verified   */
        u8       fc_map[3];      /*  FC map                */
-       u16     vlan;      /*  FCoE vlan tag/priority   */
+       __be16   vlan;     /*  FCoE vlan tag/priority   */
        u32     fka_adv_per;    /*  FIP  ka advert. period   */
        mac_t      mac;     /*  FCF mac           */
 };
diff --git a/drivers/scsi/bfa/bfa_drv.c b/drivers/scsi/bfa/bfa_drv.c
deleted file mode 100644 (file)
index 0222d7c..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-
-#include "bfa_modules.h"
-
-/*
- * BFA module list terminated by NULL
- */
-struct bfa_module_s *hal_mods[] = {
-       &hal_mod_sgpg,
-       &hal_mod_fcport,
-       &hal_mod_fcxp,
-       &hal_mod_lps,
-       &hal_mod_uf,
-       &hal_mod_rport,
-       &hal_mod_fcpim,
-       NULL
-};
-
-/*
- * Message handlers for various modules.
- */
-bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
-       bfa_isr_unhandled,      /* NONE */
-       bfa_isr_unhandled,      /* BFI_MC_IOC */
-       bfa_isr_unhandled,      /* BFI_MC_DIAG */
-       bfa_isr_unhandled,      /* BFI_MC_FLASH */
-       bfa_isr_unhandled,      /* BFI_MC_CEE */
-       bfa_fcport_isr,         /* BFI_MC_FCPORT */
-       bfa_isr_unhandled,      /* BFI_MC_IOCFC */
-       bfa_isr_unhandled,      /* BFI_MC_LL */
-       bfa_uf_isr,             /* BFI_MC_UF */
-       bfa_fcxp_isr,           /* BFI_MC_FCXP */
-       bfa_lps_isr,            /* BFI_MC_LPS */
-       bfa_rport_isr,          /* BFI_MC_RPORT */
-       bfa_itnim_isr,          /* BFI_MC_ITNIM */
-       bfa_isr_unhandled,      /* BFI_MC_IOIM_READ */
-       bfa_isr_unhandled,      /* BFI_MC_IOIM_WRITE */
-       bfa_isr_unhandled,      /* BFI_MC_IOIM_IO */
-       bfa_ioim_isr,           /* BFI_MC_IOIM */
-       bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */
-       bfa_tskim_isr,          /* BFI_MC_TSKIM */
-       bfa_isr_unhandled,      /* BFI_MC_SBOOT */
-       bfa_isr_unhandled,      /* BFI_MC_IPFC */
-       bfa_isr_unhandled,      /* BFI_MC_PORT */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-       bfa_isr_unhandled,      /* --------- */
-};
-
-
-/*
- * Message handlers for mailbox command classes
- */
-bfa_ioc_mbox_mcfunc_t  bfa_mbox_isrs[BFI_MC_MAX] = {
-       NULL,
-       NULL,                   /* BFI_MC_IOC   */
-       NULL,                   /* BFI_MC_DIAG  */
-       NULL,           /* BFI_MC_FLASH */
-       NULL,                   /* BFI_MC_CEE   */
-       NULL,                   /* BFI_MC_PORT  */
-       bfa_iocfc_isr,          /* BFI_MC_IOCFC */
-       NULL,
-};
-
-
-
-void
-bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi)
-{
-       struct bfa_port_s       *port = &bfa->modules.port;
-       u32             dm_len;
-       u8                      *dm_kva;
-       u64             dm_pa;
-
-       dm_len = bfa_port_meminfo();
-       dm_kva = bfa_meminfo_dma_virt(mi);
-       dm_pa  = bfa_meminfo_dma_phys(mi);
-
-       memset(port, 0, sizeof(struct bfa_port_s));
-       bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod);
-       bfa_port_mem_claim(port, dm_kva, dm_pa);
-
-       bfa_meminfo_dma_virt(mi) = dm_kva + dm_len;
-       bfa_meminfo_dma_phys(mi) = dm_pa + dm_len;
-}
index e929d25b09e3083d3a095c974d48f4faa464d199..0d04ba9574f9b749603d6d92bfbb117434e7de48 100644 (file)
 #ifndef __BFA_FC_H__
 #define __BFA_FC_H__
 
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 
 typedef u64 wwn_t;
-typedef u64 lun_t;
 
 #define WWN_NULL       (0)
 #define FC_SYMNAME_MAX 256     /*  max name server symbolic name size */
@@ -63,7 +62,7 @@ struct scsi_cdb_s {
  * Fibre Channel Header Structure (FCHS) definition
  */
 struct fchs_s {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u32        routing:4;   /* routing bits */
        u32        cat_info:4;  /* category info */
 #else
@@ -82,7 +81,7 @@ struct fchs_s {
        u8         df_ctl;              /* data field control */
        u16        seq_cnt;     /* sequence count */
 
-       u16        ox_id;               /* originator exchange ID */
+       __be16     ox_id;               /* originator exchange ID */
        u16        rx_id;               /* responder exchange ID */
 
        u32        ro;          /* relative offset */
@@ -316,9 +315,9 @@ enum {
 struct fc_plogi_csp_s {
        u8         verhi;       /* FC-PH high version */
        u8         verlo;       /* FC-PH low version */
-       u16        bbcred;      /* BB_Credit */
+       __be16        bbcred;   /* BB_Credit */
 
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u8         ciro:1,              /* continuously increasing RO */
                        rro:1,          /* random relative offset */
                        npiv_supp:1,    /* NPIV supported */
@@ -355,12 +354,12 @@ struct fc_plogi_csp_s {
                        hg_supp:1;
 #endif
 
-       u16        rxsz;                /* recieve data_field size */
+       __be16        rxsz;             /* recieve data_field size */
 
-       u16        conseq;
-       u16        ro_bitmap;
+       __be16        conseq;
+       __be16        ro_bitmap;
 
-       u32        e_d_tov;
+       __be32        e_d_tov;
 };
 
 /*
@@ -368,7 +367,7 @@ struct fc_plogi_csp_s {
  * FC-PH-x. Figure 78. pg. 318.
  */
 struct fc_plogi_clp_s {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u32        class_valid:1;
        u32        intermix:1;  /* class intermix supported if set =1.
                                         * valid only for class1. Reserved for
@@ -533,7 +532,7 @@ struct fc_rsi_s {
  */
 struct fc_prli_params_s {
        u32        reserved:16;
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u32        reserved1:5;
        u32        rec_support:1;
        u32        task_retry_id:1;
@@ -575,7 +574,7 @@ enum {
 struct fc_prli_params_page_s {
        u32        type:8;
        u32        codext:8;
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u32        origprocasv:1;
        u32        rsppav:1;
        u32        imagepair:1;
@@ -611,7 +610,7 @@ struct fc_prli_s {
 struct fc_prlo_params_page_s {
        u32        type:8;
        u32        type_ext:8;
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u32        opa_valid:1; /* originator process associator
                                         * valid
                                         */
@@ -647,7 +646,7 @@ struct fc_prlo_acc_params_page_s {
        u32        type:8;
        u32        type_ext:8;
 
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u32        opa_valid:1; /* originator process associator
                                         * valid
                                         */
@@ -804,7 +803,7 @@ struct fc_tprlo_params_page_s {
 u32        type:8;
 u32        type_ext:8;
 
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u32        opa_valid:1;
        u32        rpa_valid:1;
        u32        tpo_nport_valid:1;
@@ -873,7 +872,7 @@ struct fc_rscn_event_s {
 struct fc_rscn_pl_s {
        u8         command;
        u8         pagelen;
-       u16        payldlen;
+       __be16        payldlen;
        struct fc_rscn_event_s event[1];
 };
 
@@ -926,9 +925,9 @@ struct fc_rnid_common_id_data_s {
 
 struct fc_rnid_general_topology_data_s {
        u32        vendor_unique[4];
-       u32        asso_type;
+       __be32        asso_type;
        u32        phy_port_num;
-       u32        num_attached_nodes;
+       __be32        num_attached_nodes;
        u32        node_mgmt:8;
        u32        ip_version:8;
        u32        udp_tcp_port_num:16;
@@ -984,8 +983,8 @@ enum fc_rpsc_op_speed {
 };
 
 struct fc_rpsc_speed_info_s {
-       u16        port_speed_cap;      /*! see enum fc_rpsc_speed_cap */
-       u16        port_op_speed;       /*! see enum fc_rpsc_op_speed */
+       __be16        port_speed_cap;   /*! see enum fc_rpsc_speed_cap */
+       __be16        port_op_speed;    /*! see enum fc_rpsc_op_speed */
 };
 
 enum link_e2e_beacon_subcmd {
@@ -1056,9 +1055,9 @@ struct fc_rpsc_acc_s {
 
 struct fc_rpsc2_cmd_s {
        struct fc_els_cmd_s els_cmd;
-       u32     token;
+       __be32  token;
        u16     resvd;
-       u16     num_pids;       /* Number of pids in the request */
+       __be16  num_pids;       /* Number of pids in the request */
        struct  {
                u32     rsvd1:8;
                u32     pid:24;         /* port identifier */
@@ -1076,12 +1075,12 @@ enum fc_rpsc2_port_type {
  * RPSC2 portInfo entry structure
  */
 struct fc_rpsc2_port_info_s {
-    u32    pid;        /* PID */
-    u16    resvd1;
-    u16    index;      /* port number / index */
-    u8     resvd2;
-    u8    type;        /* port type N/NL/... */
-    u16    speed;      /* port Operating Speed */
+       __be32  pid;        /* PID */
+       u16     resvd1;
+       __be16  index;      /* port number / index */
+       u8      resvd2;
+       u8      type;   /* port type N/NL/... */
+       __be16  speed;      /* port Operating Speed */
 };
 
 /*
@@ -1090,7 +1089,7 @@ struct fc_rpsc2_port_info_s {
 struct fc_rpsc2_acc_s {
        u8        els_cmd;
        u8        resvd;
-    u16       num_pids;  /* Number of pids in the request */
+       __be16    num_pids;  /* Number of pids in the request */
     struct fc_rpsc2_port_info_s port_info[1];    /* port information */
 };
 
@@ -1176,9 +1175,9 @@ struct fc_srr_s {
 #define FCP_CMND_LUN_LEN    8
 
 struct fcp_cmnd_s {
-       lun_t           lun;            /* 64-bit LU number */
-       u8         crn;         /* command reference number */
-#ifdef __BIGENDIAN
+       struct scsi_lun         lun;    /* 64-bit LU number */
+       u8                      crn;    /* command reference number */
+#ifdef __BIG_ENDIAN
        u8         resvd:1,
                        priority:4,     /* FCP-3: SAM-3 priority */
                        taskattr:3;     /* scsi task attribute */
@@ -1188,7 +1187,7 @@ struct fcp_cmnd_s {
                        resvd:1;
 #endif
        u8         tm_flags;    /* task management flags */
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u8         addl_cdb_len:6,      /* additional CDB length words */
                        iodir:2;        /* read/write FCP_DATA IUs */
 #else
@@ -1200,7 +1199,7 @@ struct fcp_cmnd_s {
        /*
         * !!! additional cdb bytes follows here!!!
         */
-       u32        fcp_dl;      /* bytes to be transferred */
+       __be32        fcp_dl;   /* bytes to be transferred */
 };
 
 #define fcp_cmnd_cdb_len(_cmnd) ((_cmnd)->addl_cdb_len * 4 + FCP_CMND_CDB_LEN)
@@ -1274,7 +1273,7 @@ struct fcp_rspinfo_s {
 struct fcp_resp_s {
        u32        reserved[2]; /* 2 words reserved */
        u16        reserved2;
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u8         reserved3:3;
        u8         fcp_conf_req:1;      /* FCP_CONF is requested */
        u8         resid_flags:2;       /* underflow/overflow */
@@ -1469,7 +1468,7 @@ struct fcgs_gidpn_resp_s {
 struct fcgs_rftid_req_s {
        u32     rsvd:8;
        u32     dap:24;         /* port identifier */
-       u32     fc4_type[8];    /* fc4 types */
+       __be32  fc4_type[8];    /* fc4 types */
 };
 
 /*
@@ -1764,7 +1763,7 @@ struct fcgs_req_s {
 
 /* Accept Response to GMAL */
 struct fcgs_gmal_resp_s {
-       u32     ms_len;   /* Num of entries */
+       __be32  ms_len;   /* Num of entries */
        u8      ms_ma[256];
 };
 
@@ -1856,8 +1855,8 @@ enum fdmi_port_attribute_type {
  * FDMI attribute
  */
 struct fdmi_attr_s {
-       u16        type;
-       u16        len;
+       __be16        type;
+       __be16        len;
        u8         value[1];
 };
 
@@ -1865,7 +1864,7 @@ struct fdmi_attr_s {
  * HBA Attribute Block
  */
 struct fdmi_hba_attr_s {
-       u32        attr_count;  /* # of attributes */
+       __be32        attr_count;       /* # of attributes */
        struct fdmi_attr_s hba_attr;    /* n attributes */
 };
 
@@ -1873,7 +1872,7 @@ struct fdmi_hba_attr_s {
  * Registered Port List
  */
 struct fdmi_port_list_s {
-       u32        num_ports;   /* number Of Port Entries */
+       __be32        num_ports;        /* number Of Port Entries */
        wwn_t           port_entry;     /* one or more */
 };
 
@@ -1881,7 +1880,7 @@ struct fdmi_port_list_s {
  * Port Attribute Block
  */
 struct fdmi_port_attr_s {
-       u32        attr_count;  /* # of attributes */
+       __be32        attr_count;       /* # of attributes */
        struct fdmi_attr_s port_attr;   /* n attributes */
 };
 
index 9c725314b513f203fc3d4cfbe667f6850568564c..b7e253451654774f89c48cd6d428a557690a222f 100644 (file)
  * fcbuild.c - FC link service frame building and parsing routines
  */
 
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 #include "bfa_fcbuild.h"
 
 /*
  * static build functions
  */
 static void     fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
-                                u16 ox_id);
+                                __be16 ox_id);
 static void     fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
-                                u16 ox_id);
+                                __be16 ox_id);
 static struct fchs_s fc_els_req_tmpl;
 static struct fchs_s fc_els_rsp_tmpl;
 static struct fchs_s fc_bls_req_tmpl;
@@ -48,7 +48,7 @@ fcbuild_init(void)
        fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
        fc_els_req_tmpl.type = FC_TYPE_ELS;
        fc_els_req_tmpl.f_ctl =
-               bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
+               bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
                              FCTL_SI_XFER);
        fc_els_req_tmpl.rx_id = FC_RXID_ANY;
 
@@ -59,7 +59,7 @@ fcbuild_init(void)
        fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
        fc_els_rsp_tmpl.type = FC_TYPE_ELS;
        fc_els_rsp_tmpl.f_ctl =
-               bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
+               bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
                              FCTL_END_SEQ | FCTL_SI_XFER);
        fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
 
@@ -68,7 +68,7 @@ fcbuild_init(void)
         */
        fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
        fc_bls_req_tmpl.type = FC_TYPE_BLS;
-       fc_bls_req_tmpl.f_ctl = bfa_os_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
+       fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
        fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
 
        /*
@@ -78,7 +78,7 @@ fcbuild_init(void)
        fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
        fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
        fc_bls_rsp_tmpl.f_ctl =
-               bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
+               bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
                              FCTL_END_SEQ | FCTL_SI_XFER);
        fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
 
@@ -129,7 +129,7 @@ fcbuild_init(void)
        fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
        fcp_fchs_tmpl.type = FC_TYPE_FCP;
        fcp_fchs_tmpl.f_ctl =
-               bfa_os_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
+               bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
        fcp_fchs_tmpl.seq_id = 1;
        fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
 }
@@ -143,7 +143,7 @@ fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
        fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
        fchs->type = FC_TYPE_SERVICES;
        fchs->f_ctl =
-               bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
+               bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
                              FCTL_SI_XFER);
        fchs->rx_id = FC_RXID_ANY;
        fchs->d_id = (d_id);
@@ -157,7 +157,7 @@ fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
 }
 
 void
-fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
+fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
 {
        memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
        fchs->d_id = (d_id);
@@ -166,7 +166,7 @@ fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
 }
 
 static void
-fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
+fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
 {
        memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
        fchs->d_id = d_id;
@@ -196,7 +196,7 @@ fc_els_rsp_parse(struct fchs_s *fchs, int len)
 }
 
 static void
-fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
+fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
 {
        memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
        fchs->d_id = d_id;
@@ -206,7 +206,7 @@ fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
 
 static          u16
 fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
-                u16 ox_id, wwn_t port_name, wwn_t node_name,
+                __be16 ox_id, wwn_t port_name, wwn_t node_name,
                 u16 pdu_size, u8 els_code)
 {
        struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
@@ -232,8 +232,8 @@ fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
                u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size,
               u8 set_npiv, u8 set_auth, u16 local_bb_credits)
 {
-       u32        d_id = bfa_os_hton3b(FC_FABRIC_PORT);
-       u32     *vvl_info;
+       u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
+       __be32  *vvl_info;
 
        memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 
@@ -267,7 +267,7 @@ fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
 
 u16
 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
-                  u16 ox_id, wwn_t port_name, wwn_t node_name,
+                  __be16 ox_id, wwn_t port_name, wwn_t node_name,
                   u16 pdu_size, u16 local_bb_credits)
 {
        u32        d_id = 0;
@@ -289,7 +289,7 @@ u16
 fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
                u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size)
 {
-       u32        d_id = bfa_os_hton3b(FC_FABRIC_PORT);
+       u32        d_id = bfa_hton3b(FC_FABRIC_PORT);
 
        memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 
@@ -392,7 +392,7 @@ fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 
 u16
 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
-                 u16 ox_id, enum bfa_lport_role role)
+                 __be16 ox_id, enum bfa_lport_role role)
 {
        struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
 
@@ -456,9 +456,9 @@ fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
        return sizeof(struct fc_logo_s);
 }
 
-static          u16
+static u16
 fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
-                u32 s_id, u16 ox_id, wwn_t port_name,
+                u32 s_id, __be16 ox_id, wwn_t port_name,
                 wwn_t node_name, u8 els_code)
 {
        memset(adisc, '\0', sizeof(struct fc_adisc_s));
@@ -480,7 +480,7 @@ fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
 
 u16
 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
-               u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name)
+               u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name)
 {
        return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
                                node_name, FC_ELS_ADISC);
@@ -488,7 +488,7 @@ fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
 
 u16
 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
-                  u32 s_id, u16 ox_id, wwn_t port_name,
+                  u32 s_id, __be16 ox_id, wwn_t port_name,
                   wwn_t node_name)
 {
        return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
@@ -592,7 +592,7 @@ fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
 
 u16
 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
-                 u16 ox_id)
+                 __be16 ox_id)
 {
        struct fc_els_cmd_s *acc = pld;
 
@@ -606,7 +606,7 @@ fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 
 u16
 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
-               u32 s_id, u16 ox_id, u8 reason_code,
+               u32 s_id, __be16 ox_id, u8 reason_code,
                u8 reason_code_expl)
 {
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
@@ -622,7 +622,7 @@ fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
 
 u16
 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
-               u32 s_id, u16 ox_id, u16 rx_id)
+               u32 s_id, __be16 ox_id, u16 rx_id)
 {
        fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
 
@@ -638,7 +638,7 @@ fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
 
 u16
 fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
-               u32 s_id, u16 ox_id)
+               u32 s_id, __be16 ox_id)
 {
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
        memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
@@ -666,7 +666,7 @@ fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
 
 u16
 fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
-               u32 d_id, u32 s_id, u16 ox_id, int num_pages)
+               u32 d_id, u32 s_id, __be16 ox_id, int num_pages)
 {
        int             page;
 
@@ -690,7 +690,7 @@ fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
 
 u16
 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
-                 u32 s_id, u16 ox_id, int num_pages)
+                 u32 s_id, __be16 ox_id, int num_pages)
 {
        int             page;
 
@@ -728,7 +728,7 @@ fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
 
 u16
 fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
-                 u32 s_id, u16 ox_id, u32 data_format,
+                 u32 s_id, __be16 ox_id, u32 data_format,
                  struct fc_rnid_common_id_data_s *common_id_data,
                  struct fc_rnid_general_topology_data_s *gen_topo_data)
 {
@@ -770,10 +770,10 @@ u16
 fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
                u32 s_id, u32 *pid_list, u16 npids)
 {
-       u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_os_hton3b(d_id));
+       u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id));
        int i = 0;
 
-       fc_els_req_build(fchs, bfa_os_hton3b(dctlr_id), s_id, 0);
+       fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0);
 
        memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
 
@@ -788,7 +788,7 @@ fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
 
 u16
 fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
-               u32 d_id, u32 s_id, u16 ox_id,
+               u32 d_id, u32 s_id, __be16 ox_id,
                  struct fc_rpsc_speed_info_s *oper_speed)
 {
        memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
@@ -807,11 +807,6 @@ fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
        return sizeof(struct fc_rpsc_acc_s);
 }
 
-/*
- * TBD -
- * . get rid of unnecessary memsets
- */
-
 u16
 fc_logo_rsp_parse(struct fchs_s *fchs, int len)
 {
@@ -995,7 +990,7 @@ fc_rrq_rsp_parse(struct fchs_s *fchs, int len)
 }
 
 u16
-fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
+fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id,
                u32 reason_code, u32 reason_expl)
 {
        struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
@@ -1045,7 +1040,7 @@ fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
@@ -1061,7 +1056,7 @@ fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
@@ -1077,7 +1072,7 @@ fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
@@ -1104,7 +1099,7 @@ u16
 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
                u8 set_br_reg, u32 s_id, u16 ox_id)
 {
-       u32        d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
+       u32        d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
 
        fc_els_req_build(fchs, d_id, s_id, ox_id);
 
@@ -1121,7 +1116,7 @@ u16
 fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
                u32 s_id, u16 ox_id)
 {
-       u32        d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
+       u32        d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
        u16        payldlen;
 
        fc_els_req_build(fchs, d_id, s_id, ox_id);
@@ -1143,7 +1138,7 @@ fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
-       u32        type_value, d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        type_value, d_id = bfa_hton3b(FC_NAME_SERVER);
        u8         index;
 
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
@@ -1167,7 +1162,7 @@ fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
@@ -1187,7 +1182,7 @@ fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1);
-       u32         d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32         d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
@@ -1209,7 +1204,7 @@ fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_rspnid_req_s *rspnid =
                        (struct fcgs_rspnid_req_s *)(cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
@@ -1229,7 +1224,7 @@ fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
 
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
 
@@ -1249,7 +1244,7 @@ fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
@@ -1267,7 +1262,7 @@ fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
@@ -1286,7 +1281,7 @@ fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_rcsid_req_s *rcsid =
                        (struct fcgs_rcsid_req_s *) (cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
@@ -1304,7 +1299,7 @@ fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
@@ -1321,7 +1316,7 @@ fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_NAME_SERVER);
+       u32        d_id = bfa_hton3b(FC_NAME_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
@@ -1341,7 +1336,7 @@ fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
 {
 
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
-       u32        d_id = bfa_os_hton3b(FC_MGMT_SERVER);
+       u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
@@ -1356,7 +1351,7 @@ void
 fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
 {
        u8         index;
-       u32       *ptr = (u32 *) bit_mask;
+       __be32       *ptr = (__be32 *) bit_mask;
        u32        type_value;
 
        /*
@@ -1377,7 +1372,7 @@ fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_MGMT_SERVER);
+       u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
@@ -1397,7 +1392,7 @@ fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
 {
        struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
        fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
-       u32        d_id = bfa_os_hton3b(FC_MGMT_SERVER);
+       u32        d_id = bfa_hton3b(FC_MGMT_SERVER);
 
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
index 73abd02e53cc4c1863333eca09b9fe10e82c165b..ece51ec7620b154819a342b8fc54aa89e1242bca 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef __FCBUILD_H__
 #define __FCBUILD_H__
 
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 #include "bfa_fc.h"
 #include "bfa_defs_fcs.h"
 
@@ -138,7 +138,7 @@ u16        fc_fdisc_build(struct fchs_s *buf, struct fc_logi_s *flogi, u32 s_id,
                               u16 pdu_size);
 
 u16        fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi,
-                                  u32 s_id, u16 ox_id,
+                                  u32 s_id, __be16 ox_id,
                                   wwn_t port_name, wwn_t node_name,
                                   u16 pdu_size,
                                   u16 local_bb_credits);
@@ -186,7 +186,7 @@ u16        fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
                                   u16 pdu_size);
 
 u16        fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc,
-                       u32 d_id, u32 s_id, u16 ox_id, wwn_t port_name,
+                       u32 d_id, u32 s_id, __be16 ox_id, wwn_t port_name,
                               wwn_t node_name);
 
 enum fc_parse_status fc_adisc_parse(struct fchs_s *fchs, void *pld,
@@ -196,20 +196,20 @@ enum fc_parse_status fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len,
                                 wwn_t port_name, wwn_t node_name);
 
 u16        fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc,
-                                  u32 d_id, u32 s_id, u16 ox_id,
+                                  u32 d_id, u32 s_id, __be16 ox_id,
                                   wwn_t port_name, wwn_t node_name);
 u16        fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt,
-                               u32 d_id, u32 s_id, u16 ox_id,
+                               u32 d_id, u32 s_id, __be16 ox_id,
                                u8 reason_code, u8 reason_code_expl);
 u16        fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd,
-                               u32 d_id, u32 s_id, u16 ox_id);
+                               u32 d_id, u32 s_id, __be16 ox_id);
 u16        fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id,
                              u32 s_id, u16 ox_id);
 
 enum fc_parse_status fc_prli_rsp_parse(struct fc_prli_s *prli, int len);
 
 u16        fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
-                                 u32 s_id, u16 ox_id,
+                                 u32 s_id, __be16 ox_id,
                                  enum bfa_lport_role role);
 
 u16        fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid,
@@ -218,7 +218,7 @@ u16        fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid,
 
 u16        fc_rnid_acc_build(struct fchs_s *fchs,
                        struct fc_rnid_acc_s *rnid_acc, u32 d_id, u32 s_id,
-                       u16 ox_id, u32 data_format,
+                       __be16 ox_id, u32 data_format,
                        struct fc_rnid_common_id_data_s *common_id_data,
                        struct fc_rnid_general_topology_data_s *gen_topo_data);
 
@@ -228,7 +228,7 @@ u16        fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc,
                              u32 d_id, u32 s_id, u16 ox_id);
 u16        fc_rpsc_acc_build(struct fchs_s *fchs,
                        struct fc_rpsc_acc_s *rpsc_acc, u32 d_id, u32 s_id,
-                       u16 ox_id, struct fc_rpsc_speed_info_s *oper_speed);
+                       __be16 ox_id, struct fc_rpsc_speed_info_s *oper_speed);
 u16        fc_gid_ft_build(struct fchs_s *fchs, void *pld, u32 s_id,
                                u8 fc4_type);
 
@@ -251,7 +251,7 @@ u16        fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id,
                              u32 s_id, u16 ox_id, wwn_t port_name);
 
 u16        fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
-                                 u32 s_id, u16 ox_id);
+                                 u32 s_id, __be16 ox_id);
 
 u16        fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
                                     u16 cmd_code);
@@ -261,7 +261,7 @@ u16 fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn);
 void           fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask);
 
 void           fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
-                                        u16 ox_id);
+                                        __be16 ox_id);
 
 enum fc_parse_status   fc_els_rsp_parse(struct fchs_s *fchs, int len);
 
@@ -274,15 +274,15 @@ enum fc_parse_status      fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name,
                                        wwn_t port_name);
 
 u16 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
-               u32 s_id, u16 ox_id, u16 rx_id);
+               u32 s_id, __be16 ox_id, u16 rx_id);
 
 int fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code);
 
 u16 fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
-               u32 d_id, u32 s_id, u16 ox_id, int num_pages);
+               u32 d_id, u32 s_id, __be16 ox_id, int num_pages);
 
 u16 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc,
-               u32 d_id, u32 s_id, u16 ox_id, int num_pages);
+               u32 d_id, u32 s_id, __be16 ox_id, int num_pages);
 
 u16 fc_logo_rsp_parse(struct fchs_s *fchs, int len);
 
@@ -304,7 +304,7 @@ u16 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
 u16 fc_tprlo_rsp_parse(struct fchs_s *fchs, int len);
 
 u16 fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
-               u16 ox_id, u32 reason_code, u32 reason_expl);
+               __be16 ox_id, u32 reason_code, u32 reason_expl);
 
 u16 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
                u32 port_id);
index 135c4427801cf66abc97719c6e9fe78ea6a9a8d1..5e697f236ef30e7042b7f196bce3db8771966c21 100644 (file)
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_modules.h"
-#include "bfa_cb_ioim.h"
 
 BFA_TRC_FILE(HAL, FCPIM);
 BFA_MODULE(fcpim);
 
-
-#define bfa_fcpim_add_iostats(__l, __r, __stats)       \
-       (__l->__stats += __r->__stats)
-
-
 /*
  *  BFA ITNIM Related definitions
  */
@@ -73,10 +68,8 @@ static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
 } while (0)
 
 /*
- *  bfa_itnim_sm BFA itnim state machine
+ *  itnim state machine event
  */
-
-
 enum bfa_itnim_event {
        BFA_ITNIM_SM_CREATE = 1,        /*  itnim is created */
        BFA_ITNIM_SM_ONLINE = 2,        /*  itnim is online */
@@ -107,9 +100,6 @@ enum bfa_itnim_event {
        if ((__fcpim)->profile_start)                                   \
                (__fcpim)->profile_start(__ioim);                       \
 } while (0)
-/*
- *  hal_ioim_sm
- */
 
 /*
  * IO state machine events
@@ -221,8 +211,7 @@ static void     bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
  * forward declaration for BFA IOIM functions
  */
 static bfa_boolean_t   bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim);
-static bfa_boolean_t   bfa_ioim_sge_setup(struct bfa_ioim_s *ioim);
-static void            bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim);
+static bfa_boolean_t   bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim);
 static bfa_boolean_t   bfa_ioim_send_abort(struct bfa_ioim_s *ioim);
 static void            bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim);
 static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete);
@@ -232,7 +221,6 @@ static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
 static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
 static bfa_boolean_t    bfa_ioim_is_abortable(struct bfa_ioim_s *ioim);
 
-
 /*
  * forward declaration of BFA IO state machine
  */
@@ -260,14 +248,13 @@ static void     bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim,
                                        enum bfa_ioim_event event);
 static void    bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim,
                                        enum bfa_ioim_event event);
-
 /*
  * forward declaration for BFA TSKIM functions
  */
 static void     __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete);
 static void     __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete);
 static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim,
-                                       lun_t lun);
+                                       struct scsi_lun lun);
 static void     bfa_tskim_gather_ios(struct bfa_tskim_s *tskim);
 static void     bfa_tskim_cleanp_comp(void *tskim_cbarg);
 static void     bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim);
@@ -275,7 +262,6 @@ static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim);
 static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim);
 static void     bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim);
 
-
 /*
  * forward declaration of BFA TSKIM state machine
  */
@@ -293,13 +279,12 @@ static void     bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
                                        enum bfa_tskim_event event);
 static void     bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim,
                                        enum bfa_tskim_event event);
-
 /*
- *  hal_fcpim_mod BFA FCP Initiator Mode module
+ *  BFA FCP Initiator Mode module
  */
 
 /*
- *     Compute and return memory needed by FCP(im) module.
+ * Compute and return memory needed by FCP(im) module.
  */
 static void
 bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
@@ -357,10 +342,6 @@ bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 static void
 bfa_fcpim_detach(struct bfa_s *bfa)
 {
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-
-       bfa_ioim_detach(fcpim);
-       bfa_tskim_detach(fcpim);
 }
 
 static void
@@ -386,56 +367,6 @@ bfa_fcpim_iocdisable(struct bfa_s *bfa)
        }
 }
 
-void
-bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *lstats,
-               struct bfa_itnim_iostats_s *rstats)
-{
-       bfa_fcpim_add_iostats(lstats, rstats, total_ios);
-       bfa_fcpim_add_iostats(lstats, rstats, qresumes);
-       bfa_fcpim_add_iostats(lstats, rstats, no_iotags);
-       bfa_fcpim_add_iostats(lstats, rstats, io_aborts);
-       bfa_fcpim_add_iostats(lstats, rstats, no_tskims);
-       bfa_fcpim_add_iostats(lstats, rstats, iocomp_ok);
-       bfa_fcpim_add_iostats(lstats, rstats, iocomp_underrun);
-       bfa_fcpim_add_iostats(lstats, rstats, iocomp_overrun);
-       bfa_fcpim_add_iostats(lstats, rstats, iocomp_aborted);
-       bfa_fcpim_add_iostats(lstats, rstats, iocomp_timedout);
-       bfa_fcpim_add_iostats(lstats, rstats, iocom_nexus_abort);
-       bfa_fcpim_add_iostats(lstats, rstats, iocom_proto_err);
-       bfa_fcpim_add_iostats(lstats, rstats, iocom_dif_err);
-       bfa_fcpim_add_iostats(lstats, rstats, iocom_sqer_needed);
-       bfa_fcpim_add_iostats(lstats, rstats, iocom_res_free);
-       bfa_fcpim_add_iostats(lstats, rstats, iocom_hostabrts);
-       bfa_fcpim_add_iostats(lstats, rstats, iocom_utags);
-       bfa_fcpim_add_iostats(lstats, rstats, io_cleanups);
-       bfa_fcpim_add_iostats(lstats, rstats, io_tmaborts);
-       bfa_fcpim_add_iostats(lstats, rstats, onlines);
-       bfa_fcpim_add_iostats(lstats, rstats, offlines);
-       bfa_fcpim_add_iostats(lstats, rstats, creates);
-       bfa_fcpim_add_iostats(lstats, rstats, deletes);
-       bfa_fcpim_add_iostats(lstats, rstats, create_comps);
-       bfa_fcpim_add_iostats(lstats, rstats, delete_comps);
-       bfa_fcpim_add_iostats(lstats, rstats, sler_events);
-       bfa_fcpim_add_iostats(lstats, rstats, fw_create);
-       bfa_fcpim_add_iostats(lstats, rstats, fw_delete);
-       bfa_fcpim_add_iostats(lstats, rstats, ioc_disabled);
-       bfa_fcpim_add_iostats(lstats, rstats, cleanup_comps);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_cmnds);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_fw_rsps);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_success);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_failures);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_io_comps);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_qresumes);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_iocdowns);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_cleanups);
-       bfa_fcpim_add_iostats(lstats, rstats, tm_cleanup_comps);
-       bfa_fcpim_add_iostats(lstats, rstats, io_comps);
-       bfa_fcpim_add_iostats(lstats, rstats, input_reqs);
-       bfa_fcpim_add_iostats(lstats, rstats, output_reqs);
-       bfa_fcpim_add_iostats(lstats, rstats, rd_throughput);
-       bfa_fcpim_add_iostats(lstats, rstats, wr_throughput);
-}
-
 void
 bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
 {
@@ -454,128 +385,6 @@ bfa_fcpim_path_tov_get(struct bfa_s *bfa)
        return fcpim->path_tov / 1000;
 }
 
-bfa_status_t
-bfa_fcpim_port_iostats(struct bfa_s *bfa, struct bfa_itnim_iostats_s *stats,
-       u8 lp_tag)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-       struct list_head *qe, *qen;
-       struct bfa_itnim_s *itnim;
-
-       /* accumulate IO stats from itnim */
-       memset(stats, 0, sizeof(struct bfa_itnim_iostats_s));
-       list_for_each_safe(qe, qen, &fcpim->itnim_q) {
-               itnim = (struct bfa_itnim_s *) qe;
-               if (itnim->rport->rport_info.lp_tag != lp_tag)
-                       continue;
-               bfa_fcpim_add_stats(stats, &(itnim->stats));
-       }
-       return BFA_STATUS_OK;
-}
-bfa_status_t
-bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_itnim_iostats_s *modstats)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-       struct list_head *qe, *qen;
-       struct bfa_itnim_s *itnim;
-
-       /* accumulate IO stats from itnim */
-       memset(modstats, 0, sizeof(struct bfa_itnim_iostats_s));
-       list_for_each_safe(qe, qen, &fcpim->itnim_q) {
-               itnim = (struct bfa_itnim_s *) qe;
-               bfa_fcpim_add_stats(modstats, &(itnim->stats));
-       }
-       return BFA_STATUS_OK;
-}
-
-bfa_status_t
-bfa_fcpim_get_del_itn_stats(struct bfa_s *bfa,
-        struct bfa_fcpim_del_itn_stats_s *modstats)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-
-       *modstats = fcpim->del_itn_stats;
-
-       return BFA_STATUS_OK;
-}
-
-
-bfa_status_t
-bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time)
-{
-       struct bfa_itnim_s *itnim;
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-       struct list_head *qe, *qen;
-
-       /* accumulate IO stats from itnim */
-       list_for_each_safe(qe, qen, &fcpim->itnim_q) {
-               itnim = (struct bfa_itnim_s *) qe;
-               bfa_itnim_clear_stats(itnim);
-       }
-       fcpim->io_profile = BFA_TRUE;
-       fcpim->io_profile_start_time = time;
-       fcpim->profile_comp = bfa_ioim_profile_comp;
-       fcpim->profile_start = bfa_ioim_profile_start;
-
-       return BFA_STATUS_OK;
-}
-bfa_status_t
-bfa_fcpim_profile_off(struct bfa_s *bfa)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-       fcpim->io_profile = BFA_FALSE;
-       fcpim->io_profile_start_time = 0;
-       fcpim->profile_comp = NULL;
-       fcpim->profile_start = NULL;
-       return BFA_STATUS_OK;
-}
-
-bfa_status_t
-bfa_fcpim_port_clear_iostats(struct bfa_s *bfa, u8 lp_tag)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-       struct list_head *qe, *qen;
-       struct bfa_itnim_s *itnim;
-
-       /* clear IO stats from all active itnims */
-       list_for_each_safe(qe, qen, &fcpim->itnim_q) {
-               itnim = (struct bfa_itnim_s *) qe;
-               if (itnim->rport->rport_info.lp_tag != lp_tag)
-                       continue;
-               bfa_itnim_clear_stats(itnim);
-       }
-       return BFA_STATUS_OK;
-
-}
-
-bfa_status_t
-bfa_fcpim_clr_modstats(struct bfa_s *bfa)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-       struct list_head *qe, *qen;
-       struct bfa_itnim_s *itnim;
-
-       /* clear IO stats from all active itnims */
-       list_for_each_safe(qe, qen, &fcpim->itnim_q) {
-               itnim = (struct bfa_itnim_s *) qe;
-               bfa_itnim_clear_stats(itnim);
-       }
-       memset(&fcpim->del_itn_stats, 0,
-               sizeof(struct bfa_fcpim_del_itn_stats_s));
-
-       return BFA_STATUS_OK;
-}
-
-void
-bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-
-       bfa_assert(q_depth <= BFA_IOCFC_QDEPTH_MAX);
-
-       fcpim->q_depth = q_depth;
-}
-
 u16
 bfa_fcpim_qdepth_get(struct bfa_s *bfa)
 {
@@ -584,32 +393,12 @@ bfa_fcpim_qdepth_get(struct bfa_s *bfa)
        return fcpim->q_depth;
 }
 
-void
-bfa_fcpim_update_ioredirect(struct bfa_s *bfa)
-{
-       bfa_boolean_t ioredirect;
-
-       /*
-        * IO redirection is turned off when QoS is enabled and vice versa
-        */
-       ioredirect = bfa_fcport_is_qos_enabled(bfa) ? BFA_FALSE : BFA_TRUE;
-}
-
-void
-bfa_fcpim_set_ioredirect(struct bfa_s *bfa, bfa_boolean_t state)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
-       fcpim->ioredirect = state;
-}
-
-
-
 /*
  *  BFA ITNIM module state machine functions
  */
 
 /*
- *     Beginning/unallocated state - no events expected.
+ * Beginning/unallocated state - no events expected.
  */
 static void
 bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -630,7 +419,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 }
 
 /*
- *     Beginning state, only online event expected.
+ * Beginning state, only online event expected.
  */
 static void
 bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -733,7 +522,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
 }
 
 /*
- *     Waiting for itnim create response from firmware, a delete is pending.
+ * Waiting for itnim create response from firmware, a delete is pending.
  */
 static void
 bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
@@ -761,7 +550,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
 }
 
 /*
- *     Online state - normal parking state.
+ * Online state - normal parking state.
  */
 static void
 bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -803,7 +592,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 }
 
 /*
- *     Second level error recovery need.
+ * Second level error recovery need.
  */
 static void
 bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -834,7 +623,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 }
 
 /*
- *     Going offline. Waiting for active IO cleanup.
+ * Going offline. Waiting for active IO cleanup.
  */
 static void
 bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
@@ -871,7 +660,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
 }
 
 /*
- *     Deleting itnim. Waiting for active IO cleanup.
+ * Deleting itnim. Waiting for active IO cleanup.
  */
 static void
 bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
@@ -956,7 +745,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
 }
 
 /*
- *     Offline state.
+ * Offline state.
  */
 static void
 bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -987,9 +776,6 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
        }
 }
 
-/*
- *     IOC h/w failed state.
- */
 static void
 bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
                                enum bfa_itnim_event event)
@@ -1024,7 +810,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
 }
 
 /*
- *     Itnim is deleted, waiting for firmware response to delete.
+ * Itnim is deleted, waiting for firmware response to delete.
  */
 static void
 bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
@@ -1069,7 +855,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
 }
 
 /*
- *     Initiate cleanup of all IOs on an IOC failure.
+ * Initiate cleanup of all IOs on an IOC failure.
  */
 static void
 bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
@@ -1103,7 +889,7 @@ bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
 }
 
 /*
- *     IO cleanup completion
+ * IO cleanup completion
  */
 static void
 bfa_itnim_cleanp_comp(void *itnim_cbarg)
@@ -1115,7 +901,7 @@ bfa_itnim_cleanp_comp(void *itnim_cbarg)
 }
 
 /*
- *     Initiate cleanup of all IOs.
+ * Initiate cleanup of all IOs.
  */
 static void
 bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
@@ -1187,9 +973,6 @@ bfa_itnim_qresume(void *cbarg)
        bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME);
 }
 
-
-
-
 /*
  *  bfa_itnim_public
  */
@@ -1457,14 +1240,12 @@ bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim)
        fcpim->del_itn_stats.del_tm_iocdowns += itnim->stats.tm_iocdowns;
 }
 
-
-
 /*
- *  bfa_itnim_public
+ * bfa_itnim_public
  */
 
 /*
- *     Itnim interrupt processing.
+ * Itnim interrupt processing.
  */
 void
 bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
@@ -1507,10 +1288,8 @@ bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
        }
 }
 
-
-
 /*
- *  bfa_itnim_api
+ * bfa_itnim_api
  */
 
 struct bfa_itnim_s *
@@ -1568,31 +1347,6 @@ bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
                 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable));
 }
 
-bfa_status_t
-bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
-               struct bfa_itnim_ioprofile_s *ioprofile)
-{
-       struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(itnim->bfa);
-       if (!fcpim->io_profile)
-               return BFA_STATUS_IOPROFILE_OFF;
-
-       itnim->ioprofile.index = BFA_IOBUCKET_MAX;
-       itnim->ioprofile.io_profile_start_time =
-               bfa_io_profile_start_time(itnim->bfa);
-       itnim->ioprofile.clock_res_mul = bfa_io_lat_clock_res_mul;
-       itnim->ioprofile.clock_res_div = bfa_io_lat_clock_res_div;
-       *ioprofile = itnim->ioprofile;
-
-       return BFA_STATUS_OK;
-}
-
-void
-bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
-       struct bfa_itnim_iostats_s *stats)
-{
-       *stats = itnim->stats;
-}
-
 void
 bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
 {
@@ -1608,7 +1362,7 @@ bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
  */
 
 /*
- *     IO is not started (unallocated).
+ * IO is not started (unallocated).
  */
 static void
 bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -1635,7 +1389,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                }
 
                if (ioim->nsges > BFI_SGE_INLINE) {
-                       if (!bfa_ioim_sge_setup(ioim)) {
+                       if (!bfa_ioim_sgpg_alloc(ioim)) {
                                bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc);
                                return;
                        }
@@ -1673,7 +1427,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 }
 
 /*
- *     IO is waiting for SG pages.
+ * IO is waiting for SG pages.
  */
 static void
 bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -1720,7 +1474,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 }
 
 /*
- *     IO is active.
+ * IO is active.
  */
 static void
 bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -1786,8 +1540,8 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        case BFA_IOIM_SM_SQRETRY:
-               if (bfa_ioim_get_iotag(ioim) != BFA_TRUE) {
-                       /* max retry completed free IO */
+               if (bfa_ioim_maxretry_reached(ioim)) {
+                       /* max retry reached, free IO */
                        bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
                        bfa_ioim_move_to_comp_q(ioim);
                        bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
@@ -1804,8 +1558,8 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 }
 
 /*
-*      IO is retried with new tag.
-*/
+ * IO is retried with new tag.
+ */
 static void
 bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 {
@@ -1815,6 +1569,7 @@ bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        switch (event) {
        case BFA_IOIM_SM_FREE:
                /* abts and rrq done. Now retry the IO with new tag */
+               bfa_ioim_update_iotag(ioim);
                if (!bfa_ioim_send_ioreq(ioim)) {
                        bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
                        break;
@@ -1858,7 +1613,7 @@ bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 }
 
 /*
- *     IO is being aborted, waiting for completion from firmware.
+ * IO is being aborted, waiting for completion from firmware.
  */
 static void
 bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -1981,7 +1736,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 }
 
 /*
- *     IO is waiting for room in request CQ
+ * IO is waiting for room in request CQ
  */
 static void
 bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -2025,7 +1780,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 }
 
 /*
- *     Active IO is being aborted, waiting for room in request CQ.
+ * Active IO is being aborted, waiting for room in request CQ.
  */
 static void
 bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -2076,7 +1831,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 }
 
 /*
- *     Active IO is being cleaned up, waiting for room in request CQ.
+ * Active IO is being cleaned up, waiting for room in request CQ.
  */
 static void
 bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
@@ -2213,11 +1968,6 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 }
 
 
-
-/*
- *  hal_ioim_private
- */
-
 static void
 __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
 {
@@ -2323,7 +2073,7 @@ bfa_ioim_sgpg_alloced(void *cbarg)
 
        ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
        list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q);
-       bfa_ioim_sgpg_setup(ioim);
+       ioim->sgpg = bfa_q_first(&ioim->sgpg_q);
        bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED);
 }
 
@@ -2335,13 +2085,16 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
 {
        struct bfa_itnim_s *itnim = ioim->itnim;
        struct bfi_ioim_req_s *m;
-       static struct fcp_cmnd_s cmnd_z0 = { 0 };
-       struct bfi_sge_s      *sge;
+       static struct fcp_cmnd_s cmnd_z0 = { { { 0 } } };
+       struct bfi_sge_s *sge, *sgpge;
        u32     pgdlen = 0;
        u32     fcp_dl;
        u64 addr;
        struct scatterlist *sg;
+       struct bfa_sgpg_s *sgpg;
        struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
+       u32 i, sge_id, pgcumsz;
+       enum dma_data_direction dmadir;
 
        /*
         * check for room in queue to send request now
@@ -2359,22 +2112,61 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
         */
        m->io_tag = cpu_to_be16(ioim->iotag);
        m->rport_hdl = ioim->itnim->rport->fw_handle;
-       m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio);
+       m->io_timeout = 0;
 
-       /*
-        * build inline IO SG element here
-        */
        sge = &m->sges[0];
-       if (ioim->nsges) {
-               sg = (struct scatterlist *)scsi_sglist(cmnd);
-               addr = bfa_os_sgaddr(sg_dma_address(sg));
-               sge->sga = *(union bfi_addr_u *) &addr;
-               pgdlen = sg_dma_len(sg);
-               sge->sg_len = pgdlen;
-               sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
+       sgpg = ioim->sgpg;
+       sge_id = 0;
+       sgpge = NULL;
+       pgcumsz = 0;
+       scsi_for_each_sg(cmnd, sg, ioim->nsges, i) {
+               if (i == 0) {
+                       /* build inline IO SG element */
+                       addr = bfa_sgaddr_le(sg_dma_address(sg));
+                       sge->sga = *(union bfi_addr_u *) &addr;
+                       pgdlen = sg_dma_len(sg);
+                       sge->sg_len = pgdlen;
+                       sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
                                        BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
-               bfa_sge_to_be(sge);
-               sge++;
+                       bfa_sge_to_be(sge);
+                       sge++;
+               } else {
+                       if (sge_id == 0)
+                               sgpge = sgpg->sgpg->sges;
+
+                       addr = bfa_sgaddr_le(sg_dma_address(sg));
+                       sgpge->sga = *(union bfi_addr_u *) &addr;
+                       sgpge->sg_len = sg_dma_len(sg);
+                       pgcumsz += sgpge->sg_len;
+
+                       /* set flags */
+                       if (i < (ioim->nsges - 1) &&
+                                       sge_id < (BFI_SGPG_DATA_SGES - 1))
+                               sgpge->flags = BFI_SGE_DATA;
+                       else if (i < (ioim->nsges - 1))
+                               sgpge->flags = BFI_SGE_DATA_CPL;
+                       else
+                               sgpge->flags = BFI_SGE_DATA_LAST;
+
+                       bfa_sge_to_le(sgpge);
+
+                       sgpge++;
+                       if (i == (ioim->nsges - 1)) {
+                               sgpge->flags = BFI_SGE_PGDLEN;
+                               sgpge->sga.a32.addr_lo = 0;
+                               sgpge->sga.a32.addr_hi = 0;
+                               sgpge->sg_len = pgcumsz;
+                               bfa_sge_to_le(sgpge);
+                       } else if (++sge_id == BFI_SGPG_DATA_SGES) {
+                               sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
+                               sgpge->flags = BFI_SGE_LINK;
+                               sgpge->sga = sgpg->sgpg_pa;
+                               sgpge->sg_len = pgcumsz;
+                               bfa_sge_to_le(sgpge);
+                               sge_id = 0;
+                               pgcumsz = 0;
+                       }
+               }
        }
 
        if (ioim->nsges > BFI_SGE_INLINE) {
@@ -2391,10 +2183,17 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
         * set up I/O command parameters
         */
        m->cmnd = cmnd_z0;
-       m->cmnd.lun = bfa_cb_ioim_get_lun(ioim->dio);
-       m->cmnd.iodir = bfa_cb_ioim_get_iodir(ioim->dio);
-       m->cmnd.cdb = *(scsi_cdb_t *)bfa_cb_ioim_get_cdb(ioim->dio);
-       fcp_dl = bfa_cb_ioim_get_size(ioim->dio);
+       int_to_scsilun(cmnd->device->lun, &m->cmnd.lun);
+       dmadir = cmnd->sc_data_direction;
+       if (dmadir == DMA_TO_DEVICE)
+               m->cmnd.iodir = FCP_IODIR_WRITE;
+       else if (dmadir == DMA_FROM_DEVICE)
+               m->cmnd.iodir = FCP_IODIR_READ;
+       else
+               m->cmnd.iodir = FCP_IODIR_NONE;
+
+       m->cmnd.cdb = *(scsi_cdb_t *) cmnd->cmnd;
+       fcp_dl = scsi_bufflen(cmnd);
        m->cmnd.fcp_dl = cpu_to_be32(fcp_dl);
 
        /*
@@ -2418,28 +2217,9 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
                bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
        }
        if (itnim->seq_rec ||
-           (bfa_cb_ioim_get_size(ioim->dio) & (sizeof(u32) - 1)))
+           (scsi_bufflen(cmnd) & (sizeof(u32) - 1)))
                bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
 
-#ifdef IOIM_ADVANCED
-       m->cmnd.crn = bfa_cb_ioim_get_crn(ioim->dio);
-       m->cmnd.priority = bfa_cb_ioim_get_priority(ioim->dio);
-       m->cmnd.taskattr = bfa_cb_ioim_get_taskattr(ioim->dio);
-
-       /*
-        * Handle large CDB (>16 bytes).
-        */
-       m->cmnd.addl_cdb_len = (bfa_cb_ioim_get_cdblen(ioim->dio) -
-                                       FCP_CMND_CDB_LEN) / sizeof(u32);
-       if (m->cmnd.addl_cdb_len) {
-               memcpy(&m->cmnd.cdb + 1, (scsi_cdb_t *)
-                               bfa_cb_ioim_get_cdb(ioim->dio) + 1,
-                               m->cmnd.addl_cdb_len * sizeof(u32));
-               fcp_cmnd_fcpdl(&m->cmnd) =
-                               cpu_to_be32(bfa_cb_ioim_get_size(ioim->dio));
-       }
-#endif
-
        /*
         * queue I/O message to firmware
         */
@@ -2452,7 +2232,7 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
  * at queuing time.
  */
 static bfa_boolean_t
-bfa_ioim_sge_setup(struct bfa_ioim_s *ioim)
+bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim)
 {
        u16     nsgpgs;
 
@@ -2472,73 +2252,11 @@ bfa_ioim_sge_setup(struct bfa_ioim_s *ioim)
        }
 
        ioim->nsgpgs = nsgpgs;
-       bfa_ioim_sgpg_setup(ioim);
+       ioim->sgpg = bfa_q_first(&ioim->sgpg_q);
 
        return BFA_TRUE;
 }
 
-static void
-bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
-{
-       int             sgeid, nsges, i;
-       struct bfi_sge_s      *sge;
-       struct bfa_sgpg_s *sgpg;
-       u32     pgcumsz;
-       u64        addr;
-       struct scatterlist *sg;
-       struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
-
-       sgeid = BFI_SGE_INLINE;
-       ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);
-
-       sg = scsi_sglist(cmnd);
-       sg = sg_next(sg);
-
-       do {
-               sge = sgpg->sgpg->sges;
-               nsges = ioim->nsges - sgeid;
-               if (nsges > BFI_SGPG_DATA_SGES)
-                       nsges = BFI_SGPG_DATA_SGES;
-
-               pgcumsz = 0;
-               for (i = 0; i < nsges; i++, sge++, sgeid++, sg = sg_next(sg)) {
-                       addr = bfa_os_sgaddr(sg_dma_address(sg));
-                       sge->sga = *(union bfi_addr_u *) &addr;
-                       sge->sg_len = sg_dma_len(sg);
-                       pgcumsz += sge->sg_len;
-
-                       /*
-                        * set flags
-                        */
-                       if (i < (nsges - 1))
-                               sge->flags = BFI_SGE_DATA;
-                       else if (sgeid < (ioim->nsges - 1))
-                               sge->flags = BFI_SGE_DATA_CPL;
-                       else
-                               sge->flags = BFI_SGE_DATA_LAST;
-
-                       bfa_sge_to_le(sge);
-               }
-
-               sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
-
-               /*
-                * set the link element of each page
-                */
-               if (sgeid == ioim->nsges) {
-                       sge->flags = BFI_SGE_PGDLEN;
-                       sge->sga.a32.addr_lo = 0;
-                       sge->sga.a32.addr_hi = 0;
-               } else {
-                       sge->flags = BFI_SGE_LINK;
-                       sge->sga = sgpg->sgpg_pa;
-               }
-               sge->sg_len = pgcumsz;
-
-               bfa_sge_to_le(sge);
-       } while (sgeid < ioim->nsges);
-}
-
 /*
  * Send I/O abort request to firmware.
  */
@@ -2605,7 +2323,7 @@ bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim)
                }
                bfa_itnim_iodone(ioim->itnim);
        } else
-               bfa_tskim_iodone(ioim->iosp->tskim);
+               bfa_wc_down(&ioim->iosp->tskim->wc);
 }
 
 static bfa_boolean_t
@@ -2623,9 +2341,6 @@ bfa_ioim_is_abortable(struct bfa_ioim_s *ioim)
        return BFA_TRUE;
 }
 
-/*
- *     or after the link comes back.
- */
 void
 bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
 {
@@ -2653,11 +2368,6 @@ bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
 }
 
 
-
-/*
- *  hal_ioim_friend
- */
-
 /*
  * Memory allocation and initialization.
  */
@@ -2722,14 +2432,6 @@ bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
        }
 }
 
-/*
- * Driver detach time call.
- */
-void
-bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim)
-{
-}
-
 void
 bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 {
@@ -2825,7 +2527,7 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
        iotag = be16_to_cpu(rsp->io_tag);
 
        ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
-       bfa_assert(ioim->iotag == iotag);
+       bfa_assert(BFA_IOIM_TAG_2_ID(ioim->iotag) == iotag);
 
        bfa_trc_fp(ioim->bfa, ioim->iotag);
        bfa_ioim_cb_profile_comp(fcpim, ioim);
@@ -2833,31 +2535,6 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
        bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
 }
 
-void
-bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
-{
-       ioim->start_time = jiffies;
-}
-
-void
-bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
-{
-       u32 fcp_dl = bfa_cb_ioim_get_size(ioim->dio);
-       u32 index = bfa_ioim_get_index(fcp_dl);
-       u64 end_time = jiffies;
-       struct bfa_itnim_latency_s *io_lat =
-                       &(ioim->itnim->ioprofile.io_latency);
-       u32 val = (u32)(end_time - ioim->start_time);
-
-       bfa_itnim_ioprofile_update(ioim->itnim, index);
-
-       io_lat->count[index]++;
-       io_lat->min[index] = (io_lat->min[index] < val) ?
-               io_lat->min[index] : val;
-       io_lat->max[index] = (io_lat->max[index] > val) ?
-               io_lat->max[index] : val;
-       io_lat->avg[index] += val;
-}
 /*
  * Called by itnim to clean up IO while going offline.
  */
@@ -2903,11 +2580,6 @@ bfa_ioim_tov(struct bfa_ioim_s *ioim)
 }
 
 
-
-/*
- *  hal_ioim_api
- */
-
 /*
  * Allocate IOIM resource for initiator mode I/O request.
  */
@@ -2958,6 +2630,7 @@ bfa_ioim_free(struct bfa_ioim_s *ioim)
        bfa_stats(ioim->itnim, io_comps);
        fcpim->ios_active--;
 
+       ioim->iotag &= BFA_IOIM_IOTAG_MASK;
        list_del(&ioim->qe);
        list_add_tail(&ioim->qe, &fcpim->ioim_free_q);
 }
@@ -2973,8 +2646,7 @@ bfa_ioim_start(struct bfa_ioim_s *ioim)
         * Obtain the queue over which this request has to be issued
         */
        ioim->reqq = bfa_fcpim_ioredirect_enabled(ioim->bfa) ?
-                       bfa_cb_ioim_get_reqq(ioim->dio) :
-                       bfa_itnim_get_reqq(ioim);
+                       BFA_FALSE : bfa_itnim_get_reqq(ioim);
 
        bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
 }
@@ -2997,13 +2669,12 @@ bfa_ioim_abort(struct bfa_ioim_s *ioim)
        return BFA_STATUS_OK;
 }
 
-
 /*
  *  BFA TSKIM state machine functions
  */
 
 /*
- *     Task management command beginning state.
+ * Task management command beginning state.
  */
 static void
 bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3040,9 +2711,8 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
 }
 
 /*
- * brief
- *     TM command is active, awaiting completion from firmware to
- *     cleanup IO requests in TM scope.
+ * TM command is active, awaiting completion from firmware to
+ * cleanup IO requests in TM scope.
  */
 static void
 bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3077,8 +2747,8 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
 }
 
 /*
- *     An active TM is being cleaned up since ITN is offline. Awaiting cleanup
- *     completion event from firmware.
+ * An active TM is being cleaned up since ITN is offline. Awaiting cleanup
+ * completion event from firmware.
  */
 static void
 bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3138,7 +2808,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
 }
 
 /*
- *     Task management command is waiting for room in request CQ
+ * Task management command is waiting for room in request CQ
  */
 static void
 bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3173,8 +2843,8 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
 }
 
 /*
- *     Task management command is active, awaiting for room in request CQ
- *     to send clean up request.
+ * Task management command is active, awaiting for room in request CQ
+ * to send clean up request.
  */
 static void
 bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
@@ -3186,10 +2856,8 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
        case BFA_TSKIM_SM_DONE:
                bfa_reqq_wcancel(&tskim->reqq_wait);
                /*
-                *
                 * Fall through !!!
                 */
-
        case BFA_TSKIM_SM_QRESUME:
                bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
                bfa_tskim_send_abort(tskim);
@@ -3208,7 +2876,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
 }
 
 /*
- *     BFA callback is pending
+ * BFA callback is pending
  */
 static void
 bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
@@ -3233,12 +2901,6 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
        }
 }
 
-
-
-/*
- *  hal_tskim_private
- */
-
 static void
 __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete)
 {
@@ -3268,8 +2930,8 @@ __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete)
                                BFI_TSKIM_STS_FAILED);
 }
 
-static bfa_boolean_t
-bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
+static bfa_boolean_t
+bfa_tskim_match_scope(struct bfa_tskim_s *tskim, struct scsi_lun lun)
 {
        switch (tskim->tm_cmnd) {
        case FCP_TM_TARGET_RESET:
@@ -3279,7 +2941,7 @@ bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
        case FCP_TM_CLEAR_TASK_SET:
        case FCP_TM_LUN_RESET:
        case FCP_TM_CLEAR_ACA:
-               return (tskim->lun == lun);
+               return !memcmp(&tskim->lun, &lun, sizeof(lun));
 
        default:
                bfa_assert(0);
@@ -3289,14 +2951,16 @@ bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
 }
 
 /*
- *     Gather affected IO requests and task management commands.
+ * Gather affected IO requests and task management commands.
  */
 static void
 bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
 {
        struct bfa_itnim_s *itnim = tskim->itnim;
        struct bfa_ioim_s *ioim;
-       struct list_head        *qe, *qen;
+       struct list_head *qe, *qen;
+       struct scsi_cmnd *cmnd;
+       struct scsi_lun scsilun;
 
        INIT_LIST_HEAD(&tskim->io_q);
 
@@ -3305,8 +2969,9 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
         */
        list_for_each_safe(qe, qen, &itnim->io_q) {
                ioim = (struct bfa_ioim_s *) qe;
-               if (bfa_tskim_match_scope
-                       (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
+               cmnd = (struct scsi_cmnd *) ioim->dio;
+               int_to_scsilun(cmnd->device->lun, &scsilun);
+               if (bfa_tskim_match_scope(tskim, scsilun)) {
                        list_del(&ioim->qe);
                        list_add_tail(&ioim->qe, &tskim->io_q);
                }
@@ -3317,8 +2982,9 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
         */
        list_for_each_safe(qe, qen, &itnim->pending_q) {
                ioim = (struct bfa_ioim_s *) qe;
-               if (bfa_tskim_match_scope
-                       (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
+               cmnd = (struct scsi_cmnd *) ioim->dio;
+               int_to_scsilun(cmnd->device->lun, &scsilun);
+               if (bfa_tskim_match_scope(tskim, scsilun)) {
                        list_del(&ioim->qe);
                        list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
                        bfa_ioim_tov(ioim);
@@ -3327,7 +2993,7 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
 }
 
 /*
- *     IO cleanup completion
+ * IO cleanup completion
  */
 static void
 bfa_tskim_cleanp_comp(void *tskim_cbarg)
@@ -3339,7 +3005,7 @@ bfa_tskim_cleanp_comp(void *tskim_cbarg)
 }
 
 /*
- *     Gather affected IO requests and task management commands.
+ * Gather affected IO requests and task management commands.
  */
 static void
 bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
@@ -3359,7 +3025,7 @@ bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
 }
 
 /*
- *     Send task management request to firmware.
+ * Send task management request to firmware.
  */
 static bfa_boolean_t
 bfa_tskim_send(struct bfa_tskim_s *tskim)
@@ -3394,7 +3060,7 @@ bfa_tskim_send(struct bfa_tskim_s *tskim)
 }
 
 /*
- *     Send abort request to cleanup an active TM to firmware.
+ * Send abort request to cleanup an active TM to firmware.
  */
 static bfa_boolean_t
 bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
@@ -3425,7 +3091,7 @@ bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
 }
 
 /*
- *     Call to resume task management cmnd waiting for room in request queue.
+ * Call to resume task management cmnd waiting for room in request queue.
  */
 static void
 bfa_tskim_qresume(void *cbarg)
@@ -3451,12 +3117,6 @@ bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim)
        }
 }
 
-
-
-/*
- *  hal_tskim_friend
- */
-
 /*
  * Notification on completions from related ioim.
  */
@@ -3489,7 +3149,7 @@ bfa_tskim_cleanup(struct bfa_tskim_s *tskim)
 }
 
 /*
- *     Memory allocation and initialization.
+ * Memory allocation and initialization.
  */
 void
 bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
@@ -3521,14 +3181,6 @@ bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
        bfa_meminfo_kva(minfo) = (u8 *) tskim;
 }
 
-void
-bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim)
-{
-       /*
-       * @todo
-       */
-}
-
 void
 bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 {
@@ -3556,12 +3208,6 @@ bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 }
 
 
-
-/*
- *  hal_tskim_api
- */
-
-
 struct bfa_tskim_s *
 bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk)
 {
@@ -3585,7 +3231,7 @@ bfa_tskim_free(struct bfa_tskim_s *tskim)
 }
 
 /*
- *     Start a task management command.
+ * Start a task management command.
  *
  * @param[in]  tskim   BFA task management command instance
  * @param[in]  itnim   i-t nexus for the task management command
@@ -3596,7 +3242,8 @@ bfa_tskim_free(struct bfa_tskim_s *tskim)
  * @return None.
  */
 void
-bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim, lun_t lun,
+bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim,
+                       struct scsi_lun lun,
                        enum fcp_tm_cmnd tm_cmnd, u8 tsecs)
 {
        tskim->itnim    = itnim;
index db53717eeb4bb49912a728483c455acabed54d67..1e38dade842341731e3a137c1ee9a02e79c9a1ec 100644 (file)
@@ -41,7 +41,7 @@
        (__itnim->ioprofile.iocomps[__index]++)
 
 #define BFA_IOIM_RETRY_TAG_OFFSET 11
-#define BFA_IOIM_RETRY_TAG_MASK 0x07ff /* 2K IOs */
+#define BFA_IOIM_IOTAG_MASK 0x07ff /* 2K IOs */
 #define BFA_IOIM_RETRY_MAX 7
 
 /* Buckets are are 512 bytes to 2MB */
@@ -94,12 +94,12 @@ struct bfa_fcpim_mod_s {
        struct list_head        ioim_resfree_q; /*  IOs waiting for f/w */
        struct list_head        ioim_comp_q;    /*  IO global comp Q    */
        struct list_head        tskim_free_q;
-       u32             ios_active;     /*  current active IOs  */
-       u32             delay_comp;
+       u32                     ios_active;     /*  current active IOs  */
+       u32                     delay_comp;
        struct bfa_fcpim_del_itn_stats_s del_itn_stats;
        bfa_boolean_t           ioredirect;
        bfa_boolean_t           io_profile;
-       u32             io_profile_start_time;
+       u32                     io_profile_start_time;
        bfa_fcpim_profile_t     profile_comp;
        bfa_fcpim_profile_t     profile_start;
 };
@@ -114,25 +114,24 @@ struct bfa_ioim_s {
        struct bfa_fcpim_mod_s  *fcpim;         /*  parent fcpim module */
        struct bfa_itnim_s      *itnim;         /*  i-t-n nexus for this IO  */
        struct bfad_ioim_s      *dio;           /*  driver IO handle    */
-       u16             iotag;          /*  FWI IO tag  */
-       u16             abort_tag;      /*  unqiue abort request tag */
-       u16             nsges;          /*  number of SG elements */
-       u16             nsgpgs;         /*  number of SG pages  */
+       u16                     iotag;          /*  FWI IO tag  */
+       u16                     abort_tag;      /*  unqiue abort request tag */
+       u16                     nsges;          /*  number of SG elements */
+       u16                     nsgpgs;         /*  number of SG pages  */
        struct bfa_sgpg_s       *sgpg;          /*  first SG page       */
        struct list_head        sgpg_q;         /*  allocated SG pages  */
        struct bfa_cb_qe_s      hcb_qe;         /*  bfa callback qelem  */
        bfa_cb_cbfn_t           io_cbfn;        /*  IO completion handler */
-       struct bfa_ioim_sp_s *iosp;             /*  slow-path IO handling */
-       u8              reqq;           /*  Request queue for I/O */
-       u64 start_time;                 /*  IO's Profile start val */
+       struct bfa_ioim_sp_s    *iosp;          /*  slow-path IO handling */
+       u8                      reqq;           /*  Request queue for I/O */
+       u64                     start_time;     /*  IO's Profile start val */
 };
 
-
 struct bfa_ioim_sp_s {
        struct bfi_msg_s        comp_rspmsg;    /*  IO comp f/w response */
        u8                      *snsinfo;       /*  sense info for this IO   */
-       struct bfa_sgpg_wqe_s sgpg_wqe; /*  waitq elem for sgpg */
-       struct bfa_reqq_wait_s reqq_wait;       /*  to wait for room in reqq */
+       struct bfa_sgpg_wqe_s   sgpg_wqe;       /*  waitq elem for sgpg */
+       struct bfa_reqq_wait_s  reqq_wait;      /*  to wait for room in reqq */
        bfa_boolean_t           abort_explicit; /*  aborted by OS       */
        struct bfa_tskim_s      *tskim;         /*  Relevant TM cmd     */
 };
@@ -143,35 +142,34 @@ struct bfa_ioim_sp_s {
 struct bfa_tskim_s {
        struct list_head        qe;
        bfa_sm_t                sm;
-       struct bfa_s    *bfa;   /*  BFA module  */
+       struct bfa_s            *bfa;   /*  BFA module  */
        struct bfa_fcpim_mod_s  *fcpim; /*  parent fcpim module */
        struct bfa_itnim_s      *itnim; /*  i-t-n nexus for this IO  */
-       struct bfad_tskim_s     *dtsk;   /*  driver task mgmt cmnd      */
-       bfa_boolean_t   notify; /*  notify itnim on TM comp  */
-       lun_t   lun;    /*  lun if applicable   */
-       enum fcp_tm_cmnd        tm_cmnd;        /*  task management command  */
-       u16     tsk_tag;        /*  FWI IO tag  */
-       u8      tsecs;  /*  timeout in seconds  */
+       struct bfad_tskim_s     *dtsk;  /*  driver task mgmt cmnd       */
+       bfa_boolean_t           notify; /*  notify itnim on TM comp  */
+       struct scsi_lun         lun;    /*  lun if applicable   */
+       enum fcp_tm_cmnd        tm_cmnd; /*  task management command  */
+       u16                     tsk_tag; /*  FWI IO tag */
+       u8                      tsecs;  /*  timeout in seconds  */
        struct bfa_reqq_wait_s  reqq_wait;   /*  to wait for room in reqq */
        struct list_head        io_q;   /*  queue of affected IOs       */
-       struct bfa_wc_s wc;     /*  waiting counter     */
+       struct bfa_wc_s         wc;     /*  waiting counter     */
        struct bfa_cb_qe_s      hcb_qe; /*  bfa callback qelem  */
        enum bfi_tskim_status   tsk_status;  /*  TM status      */
 };
 
-
 /*
  * BFA i-t-n (initiator mode)
  */
 struct bfa_itnim_s {
-       struct list_head        qe;             /*  queue element       */
-       bfa_sm_t          sm;           /*  i-t-n im BFA state machine  */
-       struct bfa_s    *bfa;           /*  bfa instance        */
-       struct bfa_rport_s *rport;      /*  bfa rport   */
-       void    *ditn;          /*  driver i-t-n structure      */
+       struct list_head        qe;     /*  queue element       */
+       bfa_sm_t                sm;     /*  i-t-n im BFA state machine  */
+       struct bfa_s            *bfa;   /*  bfa instance        */
+       struct bfa_rport_s      *rport; /*  bfa rport   */
+       void                    *ditn;  /*  driver i-t-n structure      */
        struct bfi_mhdr_s       mhdr;   /*  pre-built mhdr      */
-       u8      msg_no;         /*  itnim/rport firmware handle */
-       u8      reqq;           /*  CQ for requests     */
+       u8                      msg_no; /*  itnim/rport firmware handle */
+       u8                      reqq;   /*  CQ for requests     */
        struct bfa_cb_qe_s      hcb_qe; /*  bfa callback qelem  */
        struct list_head pending_q;     /*  queue of pending IO requests */
        struct list_head io_q;          /*  queue of active IO requests */
@@ -181,19 +179,19 @@ struct bfa_itnim_s {
        bfa_boolean_t   seq_rec;        /*  SQER supported      */
        bfa_boolean_t   is_online;      /*  itnim is ONLINE for IO      */
        bfa_boolean_t   iotov_active;   /*  IO TOV timer is active       */
-       struct bfa_wc_s wc;     /*  waiting counter     */
-       struct bfa_timer_s timer;       /*  pending IO TOV               */
+       struct bfa_wc_s wc;             /*  waiting counter     */
+       struct bfa_timer_s timer;       /*  pending IO TOV       */
        struct bfa_reqq_wait_s reqq_wait; /*  to wait for room in reqq */
        struct bfa_fcpim_mod_s *fcpim;  /*  fcpim module        */
        struct bfa_itnim_iostats_s      stats;
        struct bfa_itnim_ioprofile_s  ioprofile;
 };
 
-
 #define bfa_itnim_is_online(_itnim) ((_itnim)->is_online)
 #define BFA_FCPIM_MOD(_hal) (&(_hal)->modules.fcpim_mod)
+#define BFA_IOIM_TAG_2_ID(_iotag)      ((_iotag) & BFA_IOIM_IOTAG_MASK)
 #define BFA_IOIM_FROM_TAG(_fcpim, _iotag)      \
-       (&fcpim->ioim_arr[(_iotag & BFA_IOIM_RETRY_TAG_MASK)])
+       (&fcpim->ioim_arr[(_iotag & BFA_IOIM_IOTAG_MASK)])
 #define BFA_TSKIM_FROM_TAG(_fcpim, _tmtag)     \
        (&fcpim->tskim_arr[_tmtag & (fcpim->num_tskim_reqs - 1)])
 
@@ -201,26 +199,26 @@ struct bfa_itnim_s {
        (_bfa->modules.fcpim_mod.io_profile_start_time)
 #define bfa_fcpim_get_io_profile(_bfa) \
        (_bfa->modules.fcpim_mod.io_profile)
+#define bfa_ioim_update_iotag(__ioim) do {                             \
+       uint16_t k = (__ioim)->iotag >> BFA_IOIM_RETRY_TAG_OFFSET;      \
+       k++; (__ioim)->iotag &= BFA_IOIM_IOTAG_MASK;                    \
+       (__ioim)->iotag |= k << BFA_IOIM_RETRY_TAG_OFFSET;              \
+} while (0)
 
 static inline bfa_boolean_t
-bfa_ioim_get_iotag(struct bfa_ioim_s *ioim)
+bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim)
 {
-       u16 k = ioim->iotag;
-
-       k >>= BFA_IOIM_RETRY_TAG_OFFSET; k++;
-
-       if (k > BFA_IOIM_RETRY_MAX)
+       uint16_t k = ioim->iotag >> BFA_IOIM_RETRY_TAG_OFFSET;
+       if (k < BFA_IOIM_RETRY_MAX)
                return BFA_FALSE;
-       ioim->iotag &= BFA_IOIM_RETRY_TAG_MASK;
-       ioim->iotag |= k<<BFA_IOIM_RETRY_TAG_OFFSET;
        return BFA_TRUE;
 }
+
 /*
  * function prototypes
  */
 void   bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim,
                                        struct bfa_meminfo_s *minfo);
-void   bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim);
 void   bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 void   bfa_ioim_good_comp_isr(struct bfa_s *bfa,
                                        struct bfi_msg_s *msg);
@@ -232,7 +230,6 @@ void        bfa_ioim_tov(struct bfa_ioim_s *ioim);
 
 void   bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim,
                                        struct bfa_meminfo_s *minfo);
-void   bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim);
 void   bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 void   bfa_tskim_iodone(struct bfa_tskim_s *tskim);
 void   bfa_tskim_iocdisable(struct bfa_tskim_s *tskim);
@@ -248,32 +245,14 @@ void      bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 void   bfa_itnim_iodone(struct bfa_itnim_s *itnim);
 void   bfa_itnim_tskdone(struct bfa_itnim_s *itnim);
 bfa_boolean_t   bfa_itnim_hold_io(struct bfa_itnim_s *itnim);
-void bfa_ioim_profile_comp(struct bfa_ioim_s *ioim);
-void bfa_ioim_profile_start(struct bfa_ioim_s *ioim);
-
 
 /*
  * bfa fcpim module API functions
  */
-void           bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov);
+void   bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov);
 u16    bfa_fcpim_path_tov_get(struct bfa_s *bfa);
-void           bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth);
 u16    bfa_fcpim_qdepth_get(struct bfa_s *bfa);
-bfa_status_t bfa_fcpim_get_modstats(struct bfa_s *bfa,
-        struct bfa_itnim_iostats_s *modstats);
-bfa_status_t bfa_fcpim_port_iostats(struct bfa_s *bfa,
-               struct bfa_itnim_iostats_s *stats, u8 lp_tag);
-bfa_status_t bfa_fcpim_get_del_itn_stats(struct bfa_s *bfa,
-        struct bfa_fcpim_del_itn_stats_s *modstats);
-bfa_status_t bfa_fcpim_port_clear_iostats(struct bfa_s *bfa, u8 lp_tag);
-void bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *fcpim_stats,
-               struct bfa_itnim_iostats_s *itnim_stats);
-bfa_status_t bfa_fcpim_clr_modstats(struct bfa_s *bfa);
-void           bfa_fcpim_set_ioredirect(struct bfa_s *bfa,
-                               bfa_boolean_t state);
-void           bfa_fcpim_update_ioredirect(struct bfa_s *bfa);
-bfa_status_t bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time);
-bfa_status_t bfa_fcpim_profile_off(struct bfa_s *bfa);
+
 #define bfa_fcpim_ioredirect_enabled(__bfa)                            \
        (((struct bfa_fcpim_mod_s *)(BFA_FCPIM_MOD(__bfa)))->ioredirect)
 
@@ -291,48 +270,33 @@ bfa_status_t bfa_fcpim_profile_off(struct bfa_s *bfa);
  * bfa itnim API functions
  */
 struct bfa_itnim_s *bfa_itnim_create(struct bfa_s *bfa,
-                                       struct bfa_rport_s *rport, void *itnim);
-void           bfa_itnim_delete(struct bfa_itnim_s *itnim);
-void           bfa_itnim_online(struct bfa_itnim_s *itnim,
-                                bfa_boolean_t seq_rec);
-void           bfa_itnim_offline(struct bfa_itnim_s *itnim);
-void           bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
-                       struct bfa_itnim_iostats_s *stats);
-void           bfa_itnim_clear_stats(struct bfa_itnim_s *itnim);
-bfa_status_t   bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
-               struct bfa_itnim_ioprofile_s *ioprofile);
+               struct bfa_rport_s *rport, void *itnim);
+void bfa_itnim_delete(struct bfa_itnim_s *itnim);
+void bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec);
+void bfa_itnim_offline(struct bfa_itnim_s *itnim);
+void bfa_itnim_clear_stats(struct bfa_itnim_s *itnim);
+bfa_status_t bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
+                       struct bfa_itnim_ioprofile_s *ioprofile);
+
 #define bfa_itnim_get_reqq(__ioim) (((struct bfa_ioim_s *)__ioim)->itnim->reqq)
 
 /*
- *     BFA completion callback for bfa_itnim_online().
- *
- * @param[in]          itnim           FCS or driver itnim instance
- *
- * return None
+ * BFA completion callback for bfa_itnim_online().
  */
 void   bfa_cb_itnim_online(void *itnim);
 
 /*
- *     BFA completion callback for bfa_itnim_offline().
- *
- * @param[in]          itnim           FCS or driver itnim instance
- *
- * return None
+ * BFA completion callback for bfa_itnim_offline().
  */
 void   bfa_cb_itnim_offline(void *itnim);
 void   bfa_cb_itnim_tov_begin(void *itnim);
 void   bfa_cb_itnim_tov(void *itnim);
 
 /*
- *     BFA notification to FCS/driver for second level error recovery.
- *
+ * BFA notification to FCS/driver for second level error recovery.
  * Atleast one I/O request has timedout and target is unresponsive to
  * repeated abort requests. Second level error recovery should be initiated
  * by starting implicit logout and recovery procedures.
- *
- * @param[in]          itnim           FCS or driver itnim instance
- *
- * return None
  */
 void   bfa_cb_itnim_sler(void *itnim);
 
@@ -349,10 +313,8 @@ void               bfa_ioim_start(struct bfa_ioim_s *ioim);
 bfa_status_t   bfa_ioim_abort(struct bfa_ioim_s *ioim);
 void           bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim,
                                      bfa_boolean_t iotov);
-
-
 /*
- *     I/O completion notification.
+ * I/O completion notification.
  *
  * @param[in]          dio                     driver IO structure
  * @param[in]          io_status               IO completion status
@@ -363,39 +325,31 @@ void              bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim,
  *
  * @return None
  */
-void   bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
-                                 enum bfi_ioim_status io_status,
-                                 u8 scsi_status, int sns_len,
-                                 u8 *sns_info, s32 residue);
+void bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
+                       enum bfi_ioim_status io_status,
+                       u8 scsi_status, int sns_len,
+                       u8 *sns_info, s32 residue);
 
 /*
- *     I/O good completion notification.
- *
- * @param[in]          dio                     driver IO structure
- *
- * @return None
+ * I/O good completion notification.
  */
-void   bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio);
+void bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio);
 
 /*
- *     I/O abort completion notification
- *
- * @param[in]          dio                     driver IO that was aborted
- *
- * @return None
+ * I/O abort completion notification
  */
-void   bfa_cb_ioim_abort(void *bfad, struct bfad_ioim_s *dio);
+void bfa_cb_ioim_abort(void *bfad, struct bfad_ioim_s *dio);
 
 /*
  * bfa tskim API functions
  */
-struct bfa_tskim_s     *bfa_tskim_alloc(struct bfa_s *bfa,
-                                       struct bfad_tskim_s *dtsk);
-void           bfa_tskim_free(struct bfa_tskim_s *tskim);
-void           bfa_tskim_start(struct bfa_tskim_s *tskim,
-                               struct bfa_itnim_s *itnim, lun_t lun,
-                               enum fcp_tm_cmnd tm, u8 t_secs);
-void           bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
-                                 enum bfi_tskim_status tsk_status);
+struct bfa_tskim_s *bfa_tskim_alloc(struct bfa_s *bfa,
+                       struct bfad_tskim_s *dtsk);
+void bfa_tskim_free(struct bfa_tskim_s *tskim);
+void bfa_tskim_start(struct bfa_tskim_s *tskim,
+                       struct bfa_itnim_s *itnim, struct scsi_lun lun,
+                       enum fcp_tm_cmnd tm, u8 t_secs);
+void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
+                       enum bfi_tskim_status tsk_status);
 
 #endif /* __BFA_FCPIM_H__ */
index c94502dfac664f55fd42080695989d9e1cb1697b..e3a41b88a11bcb29c7f969fc6d794875534ba8b5 100644 (file)
@@ -19,9 +19,9 @@
  *  bfa_fcs.c BFA FCS main
  */
 
+#include "bfad_drv.h"
 #include "bfa_fcs.h"
 #include "bfa_fcbuild.h"
-#include "bfad_drv.h"
 
 BFA_TRC_FILE(FCS, FCS);
 
@@ -76,7 +76,7 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
        fcs->bfad = bfad;
        fcs->min_cfg = min_cfg;
 
-       bfa_attach_fcs(bfa);
+       bfa->fcs = BFA_TRUE;
        fcbuild_init();
 
        for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
@@ -110,14 +110,6 @@ bfa_fcs_init(struct bfa_fcs_s *fcs)
        }
 }
 
-/*
- * Start FCS operations.
- */
-void
-bfa_fcs_start(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_fabric_modstart(fcs);
-}
 
 /*
  *     brief
@@ -138,22 +130,6 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
        bfa_fcs_fabric_psymb_init(&fcs->fabric);
 }
 
-/*
- *     brief
- *             FCS FDMI Driver Parameter Initialization
- *
- *     param[in]               fcs             FCS instance
- *     param[in]               fdmi_enable     TRUE/FALSE
- *
- *     return None
- */
-void
-bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
-{
-
-       fcs->fdmi_enabled = fdmi_enable;
-
-}
 /*
  *     brief
  *             FCS instance cleanup and exit.
@@ -184,18 +160,6 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
 }
 
 
-void
-bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod)
-{
-       fcs->trcmod = trcmod;
-}
-
-void
-bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs)
-{
-       bfa_wc_down(&fcs->wc);
-}
-
 /*
  * Fabric module implementation.
  */
@@ -232,31 +196,6 @@ static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
                                         u32 rsp_len,
                                         u32 resid_len,
                                         struct fchs_s *rspfchs);
-/*
- *  fcs_fabric_sm fabric state machine functions
- */
-
-/*
- * Fabric state machine events
- */
-enum bfa_fcs_fabric_event {
-       BFA_FCS_FABRIC_SM_CREATE        = 1,    /*  create from driver        */
-       BFA_FCS_FABRIC_SM_DELETE        = 2,    /*  delete from driver        */
-       BFA_FCS_FABRIC_SM_LINK_DOWN     = 3,    /*  link down from port      */
-       BFA_FCS_FABRIC_SM_LINK_UP       = 4,    /*  link up from port         */
-       BFA_FCS_FABRIC_SM_CONT_OP       = 5,    /*  flogi/auth continue op   */
-       BFA_FCS_FABRIC_SM_RETRY_OP      = 6,    /*  flogi/auth retry op      */
-       BFA_FCS_FABRIC_SM_NO_FABRIC     = 7,    /*  from flogi/auth           */
-       BFA_FCS_FABRIC_SM_PERF_EVFP     = 8,    /*  from flogi/auth           */
-       BFA_FCS_FABRIC_SM_ISOLATE       = 9,    /*  from EVFP processing     */
-       BFA_FCS_FABRIC_SM_NO_TAGGING    = 10,   /*  no VFT tagging from EVFP */
-       BFA_FCS_FABRIC_SM_DELAYED       = 11,   /*  timeout delay event      */
-       BFA_FCS_FABRIC_SM_AUTH_FAILED   = 12,   /*  auth failed       */
-       BFA_FCS_FABRIC_SM_AUTH_SUCCESS  = 13,   /*  auth successful           */
-       BFA_FCS_FABRIC_SM_DELCOMP       = 14,   /*  all vports deleted event */
-       BFA_FCS_FABRIC_SM_LOOPBACK      = 15,   /*  Received our own FLOGI   */
-       BFA_FCS_FABRIC_SM_START         = 16,   /*  from driver       */
-};
 
 static void    bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
                                         enum bfa_fcs_fabric_event event);
@@ -270,14 +209,8 @@ static void        bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
                                              enum bfa_fcs_fabric_event event);
 static void    bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
                                       enum bfa_fcs_fabric_event event);
-static void    bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
-                                             enum bfa_fcs_fabric_event event);
-static void    bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
-                                          enum bfa_fcs_fabric_event event);
 static void    bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
                                           enum bfa_fcs_fabric_event event);
-static void    bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
-                                        enum bfa_fcs_fabric_event event);
 static void    bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
                                       enum bfa_fcs_fabric_event event);
 static void    bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
@@ -337,7 +270,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
 
        case BFA_FCS_FABRIC_SM_DELETE:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
-               bfa_fcs_modexit_comp(fabric->fcs);
+               bfa_wc_down(&fabric->fcs->wc);
                break;
 
        default:
@@ -410,7 +343,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
 
        case BFA_FCS_FABRIC_SM_LOOPBACK:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
-               bfa_lps_discard(fabric->lps);
+               bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
                bfa_fcs_fabric_set_opertype(fabric);
                break;
 
@@ -424,12 +357,12 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
 
        case BFA_FCS_FABRIC_SM_LINK_DOWN:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
-               bfa_lps_discard(fabric->lps);
+               bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
                break;
 
        case BFA_FCS_FABRIC_SM_DELETE:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
-               bfa_lps_discard(fabric->lps);
+               bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
                bfa_fcs_fabric_delete(fabric);
                break;
 
@@ -481,7 +414,7 @@ bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
        switch (event) {
        case BFA_FCS_FABRIC_SM_AUTH_FAILED:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
-               bfa_lps_discard(fabric->lps);
+               bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
                break;
 
        case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
@@ -495,7 +428,7 @@ bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
 
        case BFA_FCS_FABRIC_SM_LINK_DOWN:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
-               bfa_lps_discard(fabric->lps);
+               bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
                break;
 
        case BFA_FCS_FABRIC_SM_DELETE:
@@ -511,7 +444,7 @@ bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
 /*
  *   Authentication failed
  */
-static void
+void
 bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
                              enum bfa_fcs_fabric_event event)
 {
@@ -537,7 +470,7 @@ bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
 /*
  *   Port is in loopback mode.
  */
-static void
+void
 bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
                           enum bfa_fcs_fabric_event event)
 {
@@ -573,7 +506,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
        switch (event) {
        case BFA_FCS_FABRIC_SM_LINK_DOWN:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
-               bfa_lps_discard(fabric->lps);
+               bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
                bfa_fcs_fabric_notify_offline(fabric);
                break;
 
@@ -596,7 +529,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
 /*
  *   Fabric is online - normal operating state.
  */
-static void
+void
 bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
                         enum bfa_fcs_fabric_event event)
 {
@@ -606,7 +539,7 @@ bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
        switch (event) {
        case BFA_FCS_FABRIC_SM_LINK_DOWN:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
-               bfa_lps_discard(fabric->lps);
+               bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
                bfa_fcs_fabric_notify_offline(fabric);
                break;
 
@@ -617,7 +550,7 @@ bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
 
        case BFA_FCS_FABRIC_SM_AUTH_FAILED:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
-               bfa_lps_discard(fabric->lps);
+               bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
                break;
 
        case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
@@ -677,7 +610,7 @@ bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
        bfa_trc(fabric->fcs, event);
        wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
 
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Port is isolated due to VF_ID mismatch. "
                "PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
                pwwn_ptr, fabric->fcs->port_vfid,
@@ -697,7 +630,7 @@ bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
        switch (event) {
        case BFA_FCS_FABRIC_SM_DELCOMP:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
-               bfa_fcs_modexit_comp(fabric->fcs);
+               bfa_wc_down(&fabric->fcs->wc);
                break;
 
        case BFA_FCS_FABRIC_SM_LINK_UP:
@@ -724,8 +657,8 @@ bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
        struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
 
        port_cfg->roles = BFA_LPORT_ROLE_FCP_IM;
-       port_cfg->nwwn = bfa_ioc_get_nwwn(&fabric->fcs->bfa->ioc);
-       port_cfg->pwwn = bfa_ioc_get_pwwn(&fabric->fcs->bfa->ioc);
+       port_cfg->nwwn = fabric->fcs->bfa->ioc.attr->nwwn;
+       port_cfg->pwwn = fabric->fcs->bfa->ioc.attr->pwwn;
 }
 
 /*
@@ -813,7 +746,7 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
                return;
 
        case BFA_STATUS_EPROTOCOL:
-               switch (bfa_lps_get_extstatus(fabric->lps)) {
+               switch (fabric->lps->ext_status) {
                case BFA_EPROTO_BAD_ACCEPT:
                        fabric->stats.flogi_acc_err++;
                        break;
@@ -840,26 +773,26 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
                return;
        }
 
-       fabric->bb_credit = bfa_lps_get_peer_bbcredit(fabric->lps);
+       fabric->bb_credit = fabric->lps->pr_bbcred;
        bfa_trc(fabric->fcs, fabric->bb_credit);
 
-       if (!bfa_lps_is_brcd_fabric(fabric->lps))
-               fabric->fabric_name =  bfa_lps_get_peer_nwwn(fabric->lps);
+       if (!(fabric->lps->brcd_switch))
+               fabric->fabric_name =  fabric->lps->pr_nwwn;
 
        /*
         * Check port type. It should be 1 = F-port.
         */
-       if (bfa_lps_is_fport(fabric->lps)) {
-               fabric->bport.pid = bfa_lps_get_pid(fabric->lps);
-               fabric->is_npiv = bfa_lps_is_npiv_en(fabric->lps);
-               fabric->is_auth = bfa_lps_is_authreq(fabric->lps);
+       if (fabric->lps->fport) {
+               fabric->bport.pid = fabric->lps->lp_pid;
+               fabric->is_npiv = fabric->lps->npiv_en;
+               fabric->is_auth = fabric->lps->auth_req;
                bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
        } else {
                /*
                 * Nport-2-Nport direct attached
                 */
                fabric->bport.port_topo.pn2n.rem_port_wwn =
-                       bfa_lps_get_peer_pwwn(fabric->lps);
+                       fabric->lps->pr_pwwn;
                bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
        }
 
@@ -1038,31 +971,6 @@ bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
        bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
 }
 
-/*
- *   Suspend fabric activity as part of driver suspend.
- */
-void
-bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs)
-{
-}
-
-bfa_boolean_t
-bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
-{
-       return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
-}
-
-bfa_boolean_t
-bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric)
-{
-       return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed);
-}
-
-enum bfa_port_type
-bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
-{
-       return fabric->oper_type;
-}
 
 /*
  *   Link up notification from BFA physical port module.
@@ -1123,40 +1031,6 @@ bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
        bfa_wc_down(&fabric->wc);
 }
 
-/*
- *   Base port is deleted.
- */
-void
-bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric)
-{
-       bfa_wc_down(&fabric->wc);
-}
-
-
-/*
- *    Check if fabric is online.
- *
- *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
- *
- *   @return  TRUE/FALSE
- */
-int
-bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
-{
-       return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online);
-}
-
-/*
- *     brief
- *
- */
-bfa_status_t
-bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, struct bfa_fcs_s *fcs,
-                    struct bfa_lport_cfg_s *port_cfg, struct bfad_vf_s *vf_drv)
-{
-       bfa_sm_set_state(vf, bfa_fcs_fabric_sm_uninit);
-       return BFA_STATUS_OK;
-}
 
 /*
  * Lookup for a vport withing a fabric given its pwwn
@@ -1176,18 +1050,6 @@ bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
        return NULL;
 }
 
-/*
- *    In a given fabric, return the number of lports.
- *
- *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
- *
- *   @return : 1 or more.
- */
-u16
-bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
-{
-       return fabric->num_vports;
-}
 
 /*
  *  Get OUI of the attached switch.
@@ -1207,7 +1069,7 @@ bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
        u8 *tmp;
        u16 oui;
 
-       fab_nwwn = bfa_lps_get_peer_nwwn(fabric->lps);
+       fab_nwwn = fabric->lps->pr_nwwn;
 
        tmp = (u8 *)&fab_nwwn;
        oui = (tmp[3] << 8) | tmp[4];
@@ -1235,7 +1097,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
         * external loopback cable is in place. Our own FLOGI frames are
         * sometimes looped back when switch port gets temporarily bypassed.
         */
-       if ((pid == bfa_os_ntoh3b(FC_FABRIC_PORT)) &&
+       if ((pid == bfa_ntoh3b(FC_FABRIC_PORT)) &&
            (els_cmd->els_code == FC_ELS_FLOGI) &&
            (flogi->port_name == bfa_fcs_lport_get_pwwn(&fabric->bport))) {
                bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
@@ -1245,7 +1107,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
        /*
         * FLOGI/EVFP exchanges should be consumed by base fabric.
         */
-       if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) {
+       if (fchs->d_id == bfa_hton3b(FC_FABRIC_PORT)) {
                bfa_trc(fabric->fcs, pid);
                bfa_fcs_fabric_process_uf(fabric, fchs, len);
                return;
@@ -1358,13 +1220,13 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
                return;
 
        reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
-                                   bfa_os_hton3b(FC_FABRIC_PORT),
+                                   bfa_hton3b(FC_FABRIC_PORT),
                                    n2n_port->reply_oxid, pcfg->pwwn,
                                    pcfg->nwwn,
                                    bfa_fcport_get_maxfrsize(bfa),
                                    bfa_fcport_get_rx_bbcredit(bfa));
 
-       bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
+       bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->lp_tag,
                      BFA_FALSE, FC_CLASS_3,
                      reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric,
                      FC_MAX_PDUSZ, 0);
@@ -1411,7 +1273,7 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
                wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
                wwn2str(fwwn_ptr,
                        bfa_fcs_lport_get_fabric_name(&fabric->bport));
-               BFA_LOG(KERN_WARNING, bfad, log_level,
+               BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
                        "Base port WWN = %s Fabric WWN = %s\n",
                        pwwn_ptr, fwwn_ptr);
        }
index 9cb6a55977c3ad932642a80a5eecff8cb803fe24..0fd63168573f2bb42d2318917fcaf00026a049dd 100644 (file)
 
 #define BFA_FCS_OS_STR_LEN             64
 
+/*
+ *  lps_pvt BFA LPS private functions
+ */
+
+enum bfa_lps_event {
+       BFA_LPS_SM_LOGIN        = 1,    /* login request from user      */
+       BFA_LPS_SM_LOGOUT       = 2,    /* logout request from user     */
+       BFA_LPS_SM_FWRSP        = 3,    /* f/w response to login/logout */
+       BFA_LPS_SM_RESUME       = 4,    /* space present in reqq queue  */
+       BFA_LPS_SM_DELETE       = 5,    /* lps delete from user         */
+       BFA_LPS_SM_OFFLINE      = 6,    /* Link is offline              */
+       BFA_LPS_SM_RX_CVL       = 7,    /* Rx clear virtual link        */
+       BFA_LPS_SM_SET_N2N_PID  = 8,    /* Set assigned PID for n2n */
+};
+
+
 /*
  * !!! Only append to the enums defined here to avoid any versioning
  * !!! needed between trace utility and driver version
@@ -41,13 +57,12 @@ enum {
 struct bfa_fcs_s;
 
 #define __fcs_min_cfg(__fcs)       ((__fcs)->min_cfg)
-void bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs);
 
 #define BFA_FCS_BRCD_SWITCH_OUI  0x051e
 #define N2N_LOCAL_PID      0x010000
 #define N2N_REMOTE_PID         0x020000
 #define        BFA_FCS_RETRY_TIMEOUT 2000
-#define BFA_FCS_PID_IS_WKA(pid)  ((bfa_os_ntoh3b(pid) > 0xFFF000) ?  1 : 0)
+#define BFA_FCS_PID_IS_WKA(pid)  ((bfa_ntoh3b(pid) > 0xFFF000) ?  1 : 0)
 
 
 
@@ -109,7 +124,7 @@ struct bfa_fcs_lport_loop_s {
 
 struct bfa_fcs_lport_n2n_s {
        u32        rsvd;
-       u16        reply_oxid;  /*  ox_id from the req flogi to be
+       __be16     reply_oxid;  /*  ox_id from the req flogi to be
                                         *used in flogi acc */
        wwn_t           rem_port_wwn;   /*  Attached port's wwn */
 };
@@ -316,8 +331,6 @@ void            bfa_fcs_lport_add_rport(struct bfa_fcs_lport_s *port,
                                       struct bfa_fcs_rport_s *rport);
 void            bfa_fcs_lport_del_rport(struct bfa_fcs_lport_s *port,
                                       struct bfa_fcs_rport_s *rport);
-void bfa_fcs_lport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_lport_modexit(struct bfa_fcs_s *fcs);
 void            bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *vport);
 void            bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *vport);
 void            bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *vport);
@@ -359,9 +372,6 @@ bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport);
 bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport);
 void bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
                            struct bfa_vport_attr_s *vport_attr);
-void bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
-                            struct bfa_vport_stats_s *vport_stats);
-void bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport);
 struct bfa_fcs_vport_s *bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs,
                                             u16 vf_id, wwn_t vpwwn);
 void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
@@ -406,7 +416,7 @@ struct bfa_fcs_rport_s {
        struct bfad_rport_s     *rp_drv;        /*  driver peer instance */
        u32     pid;    /*  port ID of rport */
        u16     maxfrsize;      /*  maximum frame size */
-       u16     reply_oxid;     /*  OX_ID of inbound requests */
+       __be16  reply_oxid;     /*  OX_ID of inbound requests */
        enum fc_cos     fc_cos; /*  FC classes of service supp */
        bfa_boolean_t   cisc;   /*  CISC capable device */
        bfa_boolean_t   prlo;   /*  processing prlo or LOGO */
@@ -437,32 +447,18 @@ bfa_fcs_rport_get_halrport(struct bfa_fcs_rport_s *rport)
 /*
  * bfa fcs rport API functions
  */
-bfa_status_t bfa_fcs_rport_add(struct bfa_fcs_lport_s *port, wwn_t *pwwn,
-                              struct bfa_fcs_rport_s *rport,
-                              struct bfad_rport_s *rport_drv);
-bfa_status_t bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport);
-void bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
-                           struct bfa_rport_attr_s *attr);
-void bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
-                            struct bfa_rport_stats_s *stats);
-void bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport);
 struct bfa_fcs_rport_s *bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port,
                                             wwn_t rpwwn);
 struct bfa_fcs_rport_s *bfa_fcs_rport_lookup_by_nwwn(
        struct bfa_fcs_lport_s *port, wwn_t rnwwn);
 void bfa_fcs_rport_set_del_timeout(u8 rport_tmo);
 
-void bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport,
-                            enum bfa_port_speed speed);
 void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
         struct fchs_s *fchs, u16 len);
 void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
 
 struct bfa_fcs_rport_s *bfa_fcs_rport_create(struct bfa_fcs_lport_s *port,
         u32 pid);
-void bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport);
-void bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport);
-void bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport);
 void bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
                         struct fc_logi_s *plogi_rsp);
 void bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port,
@@ -470,10 +466,8 @@ void bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port,
                                struct fc_logi_s *plogi);
 void bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
                         struct fc_logi_s *plogi);
-void bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport);
-void bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id);
+void bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id);
 
-void bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport);
 void bfa_fcs_rport_itntm_ack(struct bfa_fcs_rport_s *rport);
 void bfa_fcs_rport_fcptm_offline_done(struct bfa_fcs_rport_s *rport);
 int  bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport);
@@ -618,7 +612,7 @@ struct bfa_fcs_fdmi_hba_attr_s {
        u8         option_rom_ver[BFA_VERSION_LEN];
        u8         fw_version[8];
        u8         os_name[256];
-       u32        max_ct_pyld;
+       __be32        max_ct_pyld;
 };
 
 /*
@@ -626,9 +620,9 @@ struct bfa_fcs_fdmi_hba_attr_s {
  */
 struct bfa_fcs_fdmi_port_attr_s {
        u8         supp_fc4_types[32];  /* supported FC4 types */
-       u32        supp_speed;  /* supported speed */
-       u32        curr_speed;  /* current Speed */
-       u32        max_frm_size;        /* max frame size */
+       __be32        supp_speed;       /* supported speed */
+       __be32        curr_speed;       /* current Speed */
+       __be32        max_frm_size;     /* max frame size */
        u8         os_device_name[256]; /* OS device Name */
        u8         host_name[256];      /* host name */
 };
@@ -663,6 +657,57 @@ struct bfa_fcs_s {
        struct bfa_wc_s         wc;     /*  waiting counter */
 };
 
+/*
+ *  fcs_fabric_sm fabric state machine functions
+ */
+
+/*
+ * Fabric state machine events
+ */
+enum bfa_fcs_fabric_event {
+       BFA_FCS_FABRIC_SM_CREATE        = 1,    /*  create from driver        */
+       BFA_FCS_FABRIC_SM_DELETE        = 2,    /*  delete from driver        */
+       BFA_FCS_FABRIC_SM_LINK_DOWN     = 3,    /*  link down from port      */
+       BFA_FCS_FABRIC_SM_LINK_UP       = 4,    /*  link up from port         */
+       BFA_FCS_FABRIC_SM_CONT_OP       = 5,    /*  flogi/auth continue op   */
+       BFA_FCS_FABRIC_SM_RETRY_OP      = 6,    /*  flogi/auth retry op      */
+       BFA_FCS_FABRIC_SM_NO_FABRIC     = 7,    /*  from flogi/auth           */
+       BFA_FCS_FABRIC_SM_PERF_EVFP     = 8,    /*  from flogi/auth           */
+       BFA_FCS_FABRIC_SM_ISOLATE       = 9,    /*  from EVFP processing     */
+       BFA_FCS_FABRIC_SM_NO_TAGGING    = 10,   /*  no VFT tagging from EVFP */
+       BFA_FCS_FABRIC_SM_DELAYED       = 11,   /*  timeout delay event      */
+       BFA_FCS_FABRIC_SM_AUTH_FAILED   = 12,   /*  auth failed       */
+       BFA_FCS_FABRIC_SM_AUTH_SUCCESS  = 13,   /*  auth successful           */
+       BFA_FCS_FABRIC_SM_DELCOMP       = 14,   /*  all vports deleted event */
+       BFA_FCS_FABRIC_SM_LOOPBACK      = 15,   /*  Received our own FLOGI   */
+       BFA_FCS_FABRIC_SM_START         = 16,   /*  from driver       */
+};
+
+/*
+ *  fcs_rport_sm FCS rport state machine events
+ */
+
+enum rport_event {
+       RPSM_EVENT_PLOGI_SEND   = 1,    /*  new rport; start with PLOGI */
+       RPSM_EVENT_PLOGI_RCVD   = 2,    /*  Inbound PLOGI from remote port */
+       RPSM_EVENT_PLOGI_COMP   = 3,    /*  PLOGI completed to rport    */
+       RPSM_EVENT_LOGO_RCVD    = 4,    /*  LOGO from remote device     */
+       RPSM_EVENT_LOGO_IMP     = 5,    /*  implicit logo for SLER      */
+       RPSM_EVENT_FCXP_SENT    = 6,    /*  Frame from has been sent    */
+       RPSM_EVENT_DELETE       = 7,    /*  RPORT delete request        */
+       RPSM_EVENT_SCN          = 8,    /*  state change notification   */
+       RPSM_EVENT_ACCEPTED     = 9,    /*  Good response from remote device */
+       RPSM_EVENT_FAILED       = 10,   /*  Request to rport failed.    */
+       RPSM_EVENT_TIMEOUT      = 11,   /*  Rport SM timeout event      */
+       RPSM_EVENT_HCB_ONLINE  = 12,    /*  BFA rport online callback   */
+       RPSM_EVENT_HCB_OFFLINE = 13,    /*  BFA rport offline callback  */
+       RPSM_EVENT_FC4_OFFLINE = 14,    /*  FC-4 offline complete       */
+       RPSM_EVENT_ADDRESS_CHANGE = 15, /*  Rport's PID has changed     */
+       RPSM_EVENT_ADDRESS_DISC = 16,   /*  Need to Discover rport's PID */
+       RPSM_EVENT_PRLO_RCVD   = 17,    /*  PRLO from remote device     */
+       RPSM_EVENT_PLOGI_RETRY = 18,    /*  Retry PLOGI continously */
+};
+
 /*
  * bfa fcs API functions
  */
@@ -672,16 +717,12 @@ void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa,
 void bfa_fcs_init(struct bfa_fcs_s *fcs);
 void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
                              struct bfa_fcs_driver_info_s *driver_info);
-void bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable);
 void bfa_fcs_exit(struct bfa_fcs_s *fcs);
-void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod);
-void           bfa_fcs_start(struct bfa_fcs_s *fcs);
 
 /*
  * bfa fcs vf public functions
  */
 bfa_fcs_vf_t *bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id);
-u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
 
 /*
  * fabric protected interface functions
@@ -689,32 +730,29 @@ u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
 void bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs);
 void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs);
 void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs);
-void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs);
 void bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric);
 void bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric);
 void bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
        struct bfa_fcs_vport_s *vport);
 void bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
        struct bfa_fcs_vport_s *vport);
-int bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric);
 struct bfa_fcs_vport_s *bfa_fcs_fabric_vport_lookup(
                struct bfa_fcs_fabric_s *fabric, wwn_t pwwn);
 void bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs);
 void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric,
                struct fchs_s *fchs, u16 len);
-bfa_boolean_t  bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric);
-bfa_boolean_t  bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric);
-enum bfa_port_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric);
 void   bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric);
-void   bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric);
-bfa_status_t   bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf,
-                       struct bfa_fcs_s *fcs, struct bfa_lport_cfg_s *port_cfg,
-                       struct bfad_vf_s *vf_drv);
 void bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
               wwn_t fabric_name);
 u16 bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric);
 void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs);
 void bfa_fcs_port_attach(struct bfa_fcs_s *fcs);
+void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
+                       enum bfa_fcs_fabric_event event);
+void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
+                       enum bfa_fcs_fabric_event event);
+void bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
+                       enum bfa_fcs_fabric_event event);
 
 /*
  * BFA FCS callback interfaces
index 9662bcdeb41d64c50ab7530fd34ab17d543fc44c..5736ef8c592fb1ce4c6713f34f3b9413f9a7ec6d 100644 (file)
@@ -19,9 +19,9 @@
  *  fcpim.c - FCP initiator mode i-t nexus state machine
  */
 
+#include "bfad_drv.h"
 #include "bfa_fcs.h"
 #include "bfa_fcbuild.h"
-#include "bfad_drv.h"
 #include "bfad_im.h"
 
 BFA_TRC_FILE(FCS, FCPIM);
@@ -103,7 +103,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
                break;
 
        case BFA_FCS_ITNIM_SM_OFFLINE:
-               bfa_fcs_rport_itnim_ack(itnim->rport);
+               bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
                break;
 
        case BFA_FCS_ITNIM_SM_INITIATOR:
@@ -140,7 +140,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
        case BFA_FCS_ITNIM_SM_OFFLINE:
                bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
                bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
-               bfa_fcs_rport_itnim_ack(itnim->rport);
+               bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
                break;
 
        case BFA_FCS_ITNIM_SM_DELETE:
@@ -181,7 +181,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
        case BFA_FCS_ITNIM_SM_OFFLINE:
                bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
                bfa_fcxp_discard(itnim->fcxp);
-               bfa_fcs_rport_itnim_ack(itnim->rport);
+               bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
                break;
 
        case BFA_FCS_ITNIM_SM_INITIATOR:
@@ -217,7 +217,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
                } else {
                        /* invoke target offline */
                        bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
-                       bfa_fcs_rport_logo_imp(itnim->rport);
+                       bfa_sm_send_event(itnim->rport, RPSM_EVENT_LOGO_IMP);
                }
                break;
 
@@ -225,7 +225,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
        case BFA_FCS_ITNIM_SM_OFFLINE:
                bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
                bfa_timer_stop(&itnim->timer);
-               bfa_fcs_rport_itnim_ack(itnim->rport);
+               bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
                break;
 
        case BFA_FCS_ITNIM_SM_INITIATOR:
@@ -261,7 +261,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
                bfa_fcb_itnim_online(itnim->itnim_drv);
                wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
                wwn2str(rpwwn_buf, itnim->rport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Target (WWN = %s) is online for initiator (WWN = %s)\n",
                rpwwn_buf, lpwwn_buf);
                break;
@@ -269,7 +269,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
        case BFA_FCS_ITNIM_SM_OFFLINE:
                bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
                bfa_itnim_offline(itnim->bfa_itnim);
-               bfa_fcs_rport_itnim_ack(itnim->rport);
+               bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
                break;
 
        case BFA_FCS_ITNIM_SM_DELETE:
@@ -301,11 +301,11 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
                wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
                wwn2str(rpwwn_buf, itnim->rport->pwwn);
                if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE)
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                        "Target (WWN = %s) connectivity lost for "
                        "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf);
                else
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Target (WWN = %s) offlined by initiator (WWN = %s)\n",
                        rpwwn_buf, lpwwn_buf);
                break;
@@ -330,7 +330,7 @@ bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
        switch (event) {
        case BFA_FCS_ITNIM_SM_HCB_OFFLINE:
                bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
-               bfa_fcs_rport_itnim_ack(itnim->rport);
+               bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
                break;
 
        case BFA_FCS_ITNIM_SM_DELETE:
@@ -358,7 +358,7 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
        switch (event) {
        case BFA_FCS_ITNIM_SM_OFFLINE:
                bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
-               bfa_fcs_rport_itnim_ack(itnim->rport);
+               bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
                break;
 
        case BFA_FCS_ITNIM_SM_RSP_ERROR:
@@ -688,7 +688,7 @@ bfa_cb_itnim_sler(void *cb_arg)
 
        itnim->stats.sler++;
        bfa_trc(itnim->fcs, itnim->rport->pwwn);
-       bfa_fcs_rport_logo_imp(itnim->rport);
+       bfa_sm_send_event(itnim->rport, RPSM_EVENT_LOGO_IMP);
 }
 
 struct bfa_fcs_itnim_s *
index 377cbfff6f2ec88a467b6e8014d27c91d3b4a0c3..eb804980cde98c6750abbeb0ea50237bda3f1f79 100644 (file)
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_fcs.h"
 #include "bfa_fcbuild.h"
 #include "bfa_fc.h"
-#include "bfad_drv.h"
 
 BFA_TRC_FILE(FCS, PORT);
 
@@ -159,7 +159,7 @@ bfa_fcs_lport_sm_online(
                        bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
                        list_for_each_safe(qe, qen, &port->rport_q) {
                                rport = (struct bfa_fcs_rport_s *) qe;
-                               bfa_fcs_rport_delete(rport);
+                               bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
                        }
                }
                break;
@@ -197,7 +197,7 @@ bfa_fcs_lport_sm_offline(
                        bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
                        list_for_each_safe(qe, qen, &port->rport_q) {
                                rport = (struct bfa_fcs_rport_s *) qe;
-                               bfa_fcs_rport_delete(rport);
+                               bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
                        }
                }
                break;
@@ -309,6 +309,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
                        return;
                }
                port->pid  = rx_fchs->d_id;
+               bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
        }
 
        /*
@@ -323,6 +324,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
                        (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
                        (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
                        port->pid  = rx_fchs->d_id;
+                       bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
                        rport->pid = rx_fchs->s_id;
                }
                bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
@@ -350,7 +352,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
                 * disappeared. Send implicit LOGO to old device.
                 */
                bfa_assert(rport->pwwn != plogi->port_name);
-               bfa_fcs_rport_logo_imp(rport);
+               bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
 
                /*
                 * Inbound PLOGI from a new device (with old PID).
@@ -491,7 +493,7 @@ bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
        __port_action[port->fabric->fab_type].online(port);
 
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Logical port online: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
 
@@ -511,18 +513,19 @@ bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
        __port_action[port->fabric->fab_type].offline(port);
 
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
-       if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE)
-               BFA_LOG(KERN_ERR, bfad, log_level,
+       if (bfa_sm_cmp_state(port->fabric,
+                       bfa_fcs_fabric_sm_online) == BFA_TRUE)
+               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
        else
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Logical port taken offline: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
 
        list_for_each_safe(qe, qen, &port->rport_q) {
                rport = (struct bfa_fcs_rport_s *) qe;
-               bfa_fcs_rport_offline(rport);
+               bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
        }
 }
 
@@ -573,7 +576,7 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
        char    lpwwn_buf[BFA_STRING_32];
 
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Logical port deleted: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
 
@@ -584,33 +587,11 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
                                port->vport ? port->vport->vport_drv : NULL);
                bfa_fcs_vport_delete_comp(port->vport);
        } else {
-                bfa_fcs_fabric_port_delete_comp(port->fabric);
+               bfa_wc_down(&port->fabric->wc);
        }
 }
 
 
-
-/*
- *  fcs_lport_api BFA FCS port API
- */
-/*
- *   Module initialization
- */
-void
-bfa_fcs_lport_modinit(struct bfa_fcs_s *fcs)
-{
-
-}
-
-/*
- *   Module cleanup
- */
-void
-bfa_fcs_lport_modexit(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_modexit_comp(fcs);
-}
-
 /*
  * Unsolicited frame receive handling.
  */
@@ -623,6 +604,7 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
        struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
 
        bfa_stats(lport, uf_recvs);
+       bfa_trc(lport->fcs, fchs->type);
 
        if (!bfa_fcs_lport_is_online(lport)) {
                bfa_stats(lport, uf_recv_drops);
@@ -682,8 +664,11 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
         * Only handles ELS frames for now.
         */
        if (fchs->type != FC_TYPE_ELS) {
-               bfa_trc(lport->fcs, fchs->type);
-               bfa_assert(0);
+               bfa_trc(lport->fcs, fchs->s_id);
+               bfa_trc(lport->fcs, fchs->d_id);
+               /* ignore type FC_TYPE_FC_FSS */
+               if (fchs->type != FC_TYPE_FC_FSS)
+                       bfa_sm_fault(lport->fcs, fchs->type);
                return;
        }
 
@@ -850,8 +835,8 @@ bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
        lport->fcs = fcs;
        lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
        lport->vport = vport;
-       lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
-                                 bfa_lps_get_tag(lport->fabric->lps);
+       lport->lp_tag = (vport) ? vport->lps->lp_tag :
+                                 lport->fabric->lps->lp_tag;
 
        INIT_LIST_HEAD(&lport->rport_q);
        lport->num_rports = 0;
@@ -878,7 +863,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
                                        vport ? vport->vport_drv : NULL);
 
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "New logical port created: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
 
@@ -903,10 +888,12 @@ bfa_fcs_lport_get_attr(
        port_attr->port_cfg = port->port_cfg;
 
        if (port->fabric) {
-               port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
-               port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
+               port_attr->port_type = port->fabric->oper_type;
+               port_attr->loopback = bfa_sm_cmp_state(port->fabric,
+                               bfa_fcs_fabric_sm_loopback);
                port_attr->authfail =
-                       bfa_fcs_fabric_is_auth_failed(port->fabric);
+                       bfa_sm_cmp_state(port->fabric,
+                               bfa_fcs_fabric_sm_auth_failed);
                port_attr->fabric_name  = bfa_fcs_lport_get_fabric_name(port);
                memcpy(port_attr->fabric_ip_addr,
                        bfa_fcs_lport_get_fabric_ipaddr(port),
@@ -915,10 +902,10 @@ bfa_fcs_lport_get_attr(
                if (port->vport != NULL) {
                        port_attr->port_type = BFA_PORT_TYPE_VPORT;
                        port_attr->fpma_mac =
-                               bfa_lps_get_lp_mac(port->vport->lps);
+                               port->vport->lps->lp_mac;
                } else {
                        port_attr->fpma_mac =
-                               bfa_lps_get_lp_mac(port->fabric->lps);
+                               port->fabric->lps->lp_mac;
                }
        } else {
                port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
@@ -998,6 +985,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
            ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
             sizeof(wwn_t)) > 0) {
                port->pid = N2N_LOCAL_PID;
+               bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
                /*
                 * First, check if we know the device by pwwn.
                 */
@@ -1007,7 +995,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
                        bfa_trc(port->fcs, rport->pid);
                        bfa_trc(port->fcs, rport->pwwn);
                        rport->pid = N2N_REMOTE_PID;
-                       bfa_fcs_rport_online(rport);
+                       bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
                        return;
                }
 
@@ -1020,7 +1008,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
                        bfa_assert(rport != NULL);
                        if (rport) {
                                bfa_trc(port->fcs, rport->pwwn);
-                               bfa_fcs_rport_delete(rport);
+                               bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
                        }
                }
                bfa_fcs_rport_create(port, N2N_REMOTE_PID);
@@ -1569,6 +1557,7 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
        struct fdmi_attr_s *attr;
        u8        *curr_ptr;
        u16        len, count;
+       u16     templen;
 
        /*
         * get hba attributes
@@ -1594,69 +1583,69 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
-       attr->len = sizeof(wwn_t);
-       memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), attr->len);
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = sizeof(wwn_t);
+       memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        count++;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * Manufacturer
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
-       attr->len = (u16) strlen(fcs_hba_attr->manufacturer);
-       memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32));
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = (u16) strlen(fcs_hba_attr->manufacturer);
+       memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
+       templen = fc_roundup(templen, sizeof(u32));
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        count++;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * Serial Number
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
-       attr->len = (u16) strlen(fcs_hba_attr->serial_num);
-       memcpy(attr->value, fcs_hba_attr->serial_num, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32));
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = (u16) strlen(fcs_hba_attr->serial_num);
+       memcpy(attr->value, fcs_hba_attr->serial_num, templen);
+       templen = fc_roundup(templen, sizeof(u32));
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        count++;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * Model
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL);
-       attr->len = (u16) strlen(fcs_hba_attr->model);
-       memcpy(attr->value, fcs_hba_attr->model, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32));
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = (u16) strlen(fcs_hba_attr->model);
+       memcpy(attr->value, fcs_hba_attr->model, templen);
+       templen = fc_roundup(templen, sizeof(u32));
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        count++;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * Model Desc
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC);
-       attr->len = (u16) strlen(fcs_hba_attr->model_desc);
-       memcpy(attr->value, fcs_hba_attr->model_desc, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32));
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = (u16) strlen(fcs_hba_attr->model_desc);
+       memcpy(attr->value, fcs_hba_attr->model_desc, templen);
+       templen = fc_roundup(templen, sizeof(u32));
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        count++;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * H/W Version
@@ -1664,14 +1653,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
        if (fcs_hba_attr->hw_version[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
                attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
-               attr->len = (u16) strlen(fcs_hba_attr->hw_version);
-               memcpy(attr->value, fcs_hba_attr->hw_version, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32));
-               curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-               len += attr->len;
+               templen = (u16) strlen(fcs_hba_attr->hw_version);
+               memcpy(attr->value, fcs_hba_attr->hw_version, templen);
+               templen = fc_roundup(templen, sizeof(u32));
+               curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+               len += templen;
                count++;
-               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                                        sizeof(attr->len));
+               attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                                        sizeof(templen));
        }
 
        /*
@@ -1679,14 +1668,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
-       attr->len = (u16) strlen(fcs_hba_attr->driver_version);
-       memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32));
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;;
+       templen = (u16) strlen(fcs_hba_attr->driver_version);
+       memcpy(attr->value, fcs_hba_attr->driver_version, templen);
+       templen = fc_roundup(templen, sizeof(u32));
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;;
        count++;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * Option Rom Version
@@ -1694,14 +1683,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
        if (fcs_hba_attr->option_rom_ver[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
                attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
-               attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver);
-               memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32));
-               curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-               len += attr->len;
+               templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
+               memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
+               templen = fc_roundup(templen, sizeof(u32));
+               curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+               len += templen;
                count++;
-               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                                        sizeof(attr->len));
+               attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                                        sizeof(templen));
        }
 
        /*
@@ -1709,14 +1698,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
-       attr->len = (u16) strlen(fcs_hba_attr->driver_version);
-       memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32));
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = (u16) strlen(fcs_hba_attr->driver_version);
+       memcpy(attr->value, fcs_hba_attr->driver_version, templen);
+       templen = fc_roundup(templen, sizeof(u32));
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        count++;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * OS Name
@@ -1724,14 +1713,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
        if (fcs_hba_attr->os_name[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
                attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
-               attr->len = (u16) strlen(fcs_hba_attr->os_name);
-               memcpy(attr->value, fcs_hba_attr->os_name, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32));
-               curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-               len += attr->len;
+               templen = (u16) strlen(fcs_hba_attr->os_name);
+               memcpy(attr->value, fcs_hba_attr->os_name, templen);
+               templen = fc_roundup(templen, sizeof(u32));
+               curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+               len += templen;
                count++;
-               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                                       sizeof(attr->len));
+               attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                                       sizeof(templen));
        }
 
        /*
@@ -1739,12 +1728,12 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
-       attr->len = sizeof(fcs_hba_attr->max_ct_pyld);
-       memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len);
-       len += attr->len;
+       templen = sizeof(fcs_hba_attr->max_ct_pyld);
+       memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
+       len += templen;
        count++;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * Update size of payload
@@ -1845,6 +1834,7 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
        u8        *curr_ptr;
        u16        len;
        u8      count = 0;
+       u16     templen;
 
        /*
         * get port attributes
@@ -1863,54 +1853,54 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
-       attr->len = sizeof(fcs_port_attr.supp_fc4_types);
-       memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len);
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = sizeof(fcs_port_attr.supp_fc4_types);
+       memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        ++count;
        attr->len =
-               cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+               cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * Supported Speed
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
-       attr->len = sizeof(fcs_port_attr.supp_speed);
-       memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len);
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = sizeof(fcs_port_attr.supp_speed);
+       memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        ++count;
        attr->len =
-               cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+               cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * current Port Speed
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
-       attr->len = sizeof(fcs_port_attr.curr_speed);
-       memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len);
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = sizeof(fcs_port_attr.curr_speed);
+       memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        ++count;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * max frame size
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
        attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
-       attr->len = sizeof(fcs_port_attr.max_frm_size);
-       memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len);
-       curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-       len += attr->len;
+       templen = sizeof(fcs_port_attr.max_frm_size);
+       memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
+       curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+       len += templen;
        ++count;
-       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                            sizeof(attr->len));
+       attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                            sizeof(templen));
 
        /*
         * OS Device Name
@@ -1918,14 +1908,14 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
        if (fcs_port_attr.os_device_name[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
                attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
-               attr->len = (u16) strlen(fcs_port_attr.os_device_name);
-               memcpy(attr->value, fcs_port_attr.os_device_name, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32));
-               curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-               len += attr->len;
+               templen = (u16) strlen(fcs_port_attr.os_device_name);
+               memcpy(attr->value, fcs_port_attr.os_device_name, templen);
+               templen = fc_roundup(templen, sizeof(u32));
+               curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+               len += templen;
                ++count;
-               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                                       sizeof(attr->len));
+               attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                                       sizeof(templen));
        }
        /*
         * Host Name
@@ -1933,14 +1923,14 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
        if (fcs_port_attr.host_name[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
                attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
-               attr->len = (u16) strlen(fcs_port_attr.host_name);
-               memcpy(attr->value, fcs_port_attr.host_name, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32));
-               curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
-               len += attr->len;
+               templen = (u16) strlen(fcs_port_attr.host_name);
+               memcpy(attr->value, fcs_port_attr.host_name, templen);
+               templen = fc_roundup(templen, sizeof(u32));
+               curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+               len += templen;
                ++count;
-               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
-                               sizeof(attr->len));
+               attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+                               sizeof(templen));
        }
 
        /*
@@ -2103,7 +2093,7 @@ bfa_fcs_lport_fdmi_timeout(void *arg)
        bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
 }
 
-void
+static void
 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
                         struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
 {
@@ -2147,7 +2137,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
        hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ);
 }
 
-void
+static void
 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
                          struct bfa_fcs_fdmi_port_attr_s *port_attr)
 {
@@ -2560,7 +2550,7 @@ bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
 
        len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
                             bfa_fcs_lport_get_fcid(port),
-                                bfa_lps_get_peer_nwwn(port->fabric->lps));
+                                port->fabric->lps->pr_nwwn);
 
        bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
                          FC_CLASS_3, len, &fchs,
@@ -2760,7 +2750,7 @@ bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
 
        len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
                             bfa_fcs_lport_get_fcid(port),
-                                bfa_lps_get_peer_nwwn(port->fabric->lps));
+                                port->fabric->lps->pr_nwwn);
 
        bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
                          FC_CLASS_3, len, &fchs,
@@ -2836,7 +2826,7 @@ bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        ms->fcxp = fcxp;
 
        len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
-                            bfa_os_hton3b(FC_MGMT_SERVER),
+                            bfa_hton3b(FC_MGMT_SERVER),
                             bfa_fcs_lport_get_fcid(port), 0,
                             port->port_cfg.pwwn, port->port_cfg.nwwn,
                                 bfa_fcport_get_maxfrsize(port->fcs->bfa));
@@ -3593,7 +3583,7 @@ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
        ns->fcxp = fcxp;
 
        len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
-                            bfa_os_hton3b(FC_NAME_SERVER),
+                            bfa_hton3b(FC_NAME_SERVER),
                             bfa_fcs_lport_get_fcid(port), 0,
                             port->port_cfg.pwwn, port->port_cfg.nwwn,
                                 bfa_fcport_get_maxfrsize(port->fcs->bfa));
@@ -4150,7 +4140,7 @@ bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
        bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
 }
 
-void
+static void
 bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
 {
 
@@ -4352,8 +4342,8 @@ bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        /* Handle VU registrations for Base port only */
        if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
                len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
-                               bfa_lps_is_brcd_fabric(port->fabric->lps),
-                                                       port->pid, 0);
+                               port->fabric->lps->brcd_switch,
+                               port->pid, 0);
        } else {
            len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
                                    BFA_FALSE,
@@ -4672,7 +4662,7 @@ bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
 
        while ((qe != qh) && (i < nrports)) {
                rport = (struct bfa_fcs_rport_s *) qe;
-               if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
+               if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
                        qe = bfa_q_next(qe);
                        bfa_trc(fcs, (u32) rport->pwwn);
                        bfa_trc(fcs, rport->pid);
@@ -4720,7 +4710,7 @@ bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
 
        while ((qe != qh) && (i < *nrports)) {
                rport = (struct bfa_fcs_rport_s *) qe;
-               if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
+               if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
                        qe = bfa_q_next(qe);
                        bfa_trc(fcs, (u32) rport->pwwn);
                        bfa_trc(fcs, rport->pid);
@@ -4771,7 +4761,7 @@ bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
 
        while (qe != qh) {
                rport = (struct bfa_fcs_rport_s *) qe;
-               if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000) ||
+               if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
                        (bfa_fcs_rport_get_state(rport) ==
                          BFA_RPORT_OFFLINE)) {
                        qe = bfa_q_next(qe);
@@ -4853,7 +4843,7 @@ bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
                port_info->max_vports_supp =
                        bfa_lps_get_max_vport(port->fcs->bfa);
                port_info->num_vports_inuse =
-                       bfa_fcs_fabric_vport_count(port->fabric);
+                       port->fabric->num_vports;
                port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
                port_info->num_rports_inuse = port->num_rports;
        } else {
@@ -4997,7 +4987,8 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
 
        switch (event) {
        case BFA_FCS_VPORT_SM_START:
-               if (bfa_fcs_fabric_is_online(__vport_fabric(vport))
+               if (bfa_sm_cmp_state(__vport_fabric(vport),
+                                       bfa_fcs_fabric_sm_online)
                    && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
                        bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
                        bfa_fcs_vport_do_fdisc(vport);
@@ -5080,13 +5071,13 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
        switch (event) {
        case BFA_FCS_VPORT_SM_DELETE:
                bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
-               bfa_lps_discard(vport->lps);
+               bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
                bfa_fcs_lport_delete(&vport->lport);
                break;
 
        case BFA_FCS_VPORT_SM_OFFLINE:
                bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
-               bfa_lps_discard(vport->lps);
+               bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
                break;
 
        case BFA_FCS_VPORT_SM_RSP_OK:
@@ -5166,7 +5157,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
 
        case BFA_FCS_VPORT_SM_OFFLINE:
                bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
-               bfa_lps_discard(vport->lps);
+               bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
                bfa_fcs_lport_offline(&vport->lport);
                break;
 
@@ -5266,7 +5257,7 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
 
        switch (event) {
        case BFA_FCS_VPORT_SM_OFFLINE:
-               bfa_lps_discard(vport->lps);
+               bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
                /*
                 * !!! fall through !!!
                 */
@@ -5305,14 +5296,14 @@ bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
 static void
 bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
 {
-       u8              lsrjt_rsn = bfa_lps_get_lsrjt_rsn(vport->lps);
-       u8              lsrjt_expl = bfa_lps_get_lsrjt_expl(vport->lps);
+       u8              lsrjt_rsn = vport->lps->lsrjt_rsn;
+       u8              lsrjt_expl = vport->lps->lsrjt_expl;
 
        bfa_trc(__vport_fcs(vport), lsrjt_rsn);
        bfa_trc(__vport_fcs(vport), lsrjt_expl);
 
        /* For certain reason codes, we don't want to retry. */
-       switch (bfa_lps_get_lsrjt_expl(vport->lps)) {
+       switch (vport->lps->lsrjt_expl) {
        case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
        case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
                if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
@@ -5476,7 +5467,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
        if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
                return BFA_STATUS_VPORT_EXISTS;
 
-       if (bfa_fcs_fabric_vport_count(&fcs->fabric) ==
+       if (fcs->fabric.num_vports ==
                        bfa_lps_get_max_vport(fcs->bfa))
                return BFA_STATUS_VPORT_MAX;
 
@@ -5618,33 +5609,6 @@ bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
        attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
 }
 
-/*
- *     Use this function to get vport's statistics.
- *
- *     param[in]       vport   pointer to bfa_fcs_vport_t.
- *     param[out]      stats   pointer to return vport statistics in
- *
- *     return None
- */
-void
-bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
-                       struct bfa_vport_stats_s *stats)
-{
-       *stats = vport->vport_stats;
-}
-
-/*
- *     Use this function to clear vport's statistics.
- *
- *     param[in]       vport   pointer to bfa_fcs_vport_t.
- *
- *     return None
- */
-void
-bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport)
-{
-       memset(&vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s));
-}
 
 /*
  *     Lookup a virtual port. Excludes base port from lookup.
@@ -5684,7 +5648,7 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
                /*
                 * Initialiaze the V-Port fields
                 */
-               __vport_fcid(vport) = bfa_lps_get_pid(vport->lps);
+               __vport_fcid(vport) = vport->lps->lp_pid;
                vport->vport_stats.fdisc_accepts++;
                bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
                break;
@@ -5697,7 +5661,7 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
                break;
 
        case BFA_STATUS_EPROTOCOL:
-               switch (bfa_lps_get_extstatus(vport->lps)) {
+               switch (vport->lps->ext_status) {
                case BFA_EPROTO_BAD_ACCEPT:
                        vport->vport_stats.fdisc_acc_bad++;
                        break;
index 47f35c0ef29a0c69f5d6842a6db0d173a0195e84..711f2d992a979c0bb1f7bb86986b4f7594bde825 100644 (file)
@@ -19,9 +19,9 @@
  *  rport.c Remote port implementation.
  */
 
+#include "bfad_drv.h"
 #include "bfa_fcs.h"
 #include "bfa_fcbuild.h"
-#include "bfad_drv.h"
 
 BFA_TRC_FILE(FCS, RPORT);
 
@@ -75,30 +75,6 @@ static void  bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
 static void    bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
                                struct fchs_s *rx_fchs, u16 len);
 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
-/*
- *  fcs_rport_sm FCS rport state machine events
- */
-
-enum rport_event {
-       RPSM_EVENT_PLOGI_SEND   = 1,    /*  new rport; start with PLOGI */
-       RPSM_EVENT_PLOGI_RCVD   = 2,    /*  Inbound PLOGI from remote port */
-       RPSM_EVENT_PLOGI_COMP   = 3,    /*  PLOGI completed to rport    */
-       RPSM_EVENT_LOGO_RCVD    = 4,    /*  LOGO from remote device     */
-       RPSM_EVENT_LOGO_IMP     = 5,    /*  implicit logo for SLER      */
-       RPSM_EVENT_FCXP_SENT    = 6,    /*  Frame from has been sent    */
-       RPSM_EVENT_DELETE       = 7,    /*  RPORT delete request        */
-       RPSM_EVENT_SCN          = 8,    /*  state change notification   */
-       RPSM_EVENT_ACCEPTED     = 9,    /*  Good response from remote device */
-       RPSM_EVENT_FAILED       = 10,   /*  Request to rport failed.    */
-       RPSM_EVENT_TIMEOUT      = 11,   /*  Rport SM timeout event      */
-       RPSM_EVENT_HCB_ONLINE  = 12,    /*  BFA rport online callback   */
-       RPSM_EVENT_HCB_OFFLINE = 13,    /*  BFA rport offline callback  */
-       RPSM_EVENT_FC4_OFFLINE = 14,    /*  FC-4 offline complete       */
-       RPSM_EVENT_ADDRESS_CHANGE = 15, /*  Rport's PID has changed     */
-       RPSM_EVENT_ADDRESS_DISC = 16,   /*  Need to Discover rport's PID */
-       RPSM_EVENT_PRLO_RCVD   = 17,    /*  PRLO from remote device     */
-       RPSM_EVENT_PLOGI_RETRY = 18,    /*  Retry PLOGI continously */
-};
 
 static void    bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
                                        enum rport_event event);
@@ -498,24 +474,24 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
 
        case RPSM_EVENT_LOGO_RCVD:
                bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
-               bfa_rport_offline(rport->bfa_rport);
+               bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
                break;
 
        case RPSM_EVENT_LOGO_IMP:
        case RPSM_EVENT_ADDRESS_CHANGE:
                bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
-               bfa_rport_offline(rport->bfa_rport);
+               bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
                break;
 
        case RPSM_EVENT_PLOGI_RCVD:
                bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
-               bfa_rport_offline(rport->bfa_rport);
+               bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
                bfa_fcs_rport_send_plogiacc(rport, NULL);
                break;
 
        case RPSM_EVENT_DELETE:
                bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
-               bfa_rport_offline(rport->bfa_rport);
+               bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
                break;
 
        case RPSM_EVENT_SCN:
@@ -824,7 +800,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
        switch (event) {
        case RPSM_EVENT_FC4_OFFLINE:
                bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
-               bfa_rport_offline(rport->bfa_rport);
+               bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
                break;
 
        case RPSM_EVENT_DELETE:
@@ -856,7 +832,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
        switch (event) {
        case RPSM_EVENT_FC4_OFFLINE:
                bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
-               bfa_rport_offline(rport->bfa_rport);
+               bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
                break;
 
        default:
@@ -878,7 +854,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
        switch (event) {
        case RPSM_EVENT_FC4_OFFLINE:
                bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
-               bfa_rport_offline(rport->bfa_rport);
+               bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
                break;
 
        case RPSM_EVENT_SCN:
@@ -1459,7 +1435,7 @@ bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
                        twin->stats.plogi_rcvd    += rport->stats.plogi_rcvd;
                        twin->stats.plogi_accs++;
 
-                       bfa_fcs_rport_delete(rport);
+                       bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
 
                        bfa_fcs_rport_update(twin, plogi_rsp);
                        twin->pid = rsp_fchs->s_id;
@@ -1998,7 +1974,8 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
                rport->itnim = bfa_fcs_itnim_create(rport);
                if (!rport->itnim) {
                        bfa_trc(fcs, rpid);
-                       bfa_rport_delete(rport->bfa_rport);
+                       bfa_sm_send_event(rport->bfa_rport,
+                                               BFA_RPORT_SM_DELETE);
                        kfree(rport_drv);
                        return NULL;
                }
@@ -2032,7 +2009,7 @@ bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
                        bfa_fcs_rpf_rport_offline(rport);
        }
 
-       bfa_rport_delete(rport->bfa_rport);
+       bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
        bfa_fcs_lport_del_rport(port, rport);
        kfree(rport->rp_drv);
 }
@@ -2056,7 +2033,7 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
        wwn2str(rpwwn_buf, rport->pwwn);
        if (!BFA_FCS_PID_IS_WKA(rport->pid))
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
                rpwwn_buf, lpwwn_buf);
 }
@@ -2075,12 +2052,12 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
        wwn2str(rpwwn_buf, rport->pwwn);
        if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
                if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE)
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "Remote port (WWN = %s) connectivity lost for "
                                "logical port (WWN = %s)\n",
                                rpwwn_buf, lpwwn_buf);
                else
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "Remote port (WWN = %s) offlined by "
                                "logical port (WWN = %s)\n",
                                rpwwn_buf, lpwwn_buf);
@@ -2307,39 +2284,7 @@ bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
        bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
 }
 
-/*
- * Called by bport/vport to delete a remote port instance.
- *
- * Rport delete is called under the following conditions:
- *             - vport is deleted
- *             - vf is deleted
- *             - explicit request from OS to delete rport
- */
-void
-bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport)
-{
-       bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
-}
 
-/*
- * Called by bport/vport to  when a target goes offline.
- *
- */
-void
-bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport)
-{
-       bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
-}
-
-/*
- * Called by bport in n2n when a target (attached port) becomes online.
- *
- */
-void
-bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport)
-{
-       bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
-}
 /*
  *     Called by bport/vport to notify SCN for the remote port
  */
@@ -2350,23 +2295,6 @@ bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
        bfa_sm_send_event(rport, RPSM_EVENT_SCN);
 }
 
-/*
- *     Called by       fcpim to notify that the ITN cleanup is done.
- */
-void
-bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport)
-{
-       bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
-}
-
-/*
- *     Called by fcptm to notify that the ITN cleanup is done.
- */
-void
-bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport)
-{
-       bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
-}
 
 /*
  *     brief
@@ -2461,15 +2389,6 @@ bfa_cb_rport_qos_scn_prio(void *cbarg,
        bfa_trc(rport->fcs, rport->pwwn);
 }
 
-/*
- *             Called to process any unsolicted frames from this remote port
- */
-void
-bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport)
-{
-       bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
-}
-
 /*
  *             Called to process any unsolicted frames from this remote port
  */
@@ -2586,6 +2505,7 @@ bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
        return bfa_sm_to_state(rport_sm_table, rport->sm);
 }
 
+
 /*
  *     brief
  *              Called by the Driver to set rport delete/ageout timeout
@@ -2602,7 +2522,7 @@ bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
                bfa_fcs_rport_del_timeout = rport_tmo * 1000;
 }
 void
-bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id)
+bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
 {
        bfa_trc(rport->fcs, rport->pid);
 
@@ -2621,106 +2541,6 @@ bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id)
  *  fcs_rport_api FCS rport API.
  */
 
-/*
- *     Direct API to add a target by port wwn. This interface is used, for
- *     example, by bios when target pwwn is known from boot lun configuration.
- */
-bfa_status_t
-bfa_fcs_rport_add(struct bfa_fcs_lport_s *port, wwn_t *pwwn,
-               struct bfa_fcs_rport_s *rport, struct bfad_rport_s *rport_drv)
-{
-       bfa_trc(port->fcs, *pwwn);
-
-       return BFA_STATUS_OK;
-}
-
-/*
- *     Direct API to remove a target and its associated resources. This
- *     interface is used, for example, by driver to remove target
- *     ports from the target list for a VM.
- */
-bfa_status_t
-bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in)
-{
-
-       struct bfa_fcs_rport_s *rport;
-
-       bfa_trc(rport_in->fcs, rport_in->pwwn);
-
-       rport = bfa_fcs_lport_get_rport_by_pwwn(rport_in->port, rport_in->pwwn);
-       if (rport == NULL) {
-               /*
-                * TBD Error handling
-                */
-               bfa_trc(rport_in->fcs, rport_in->pid);
-               return BFA_STATUS_UNKNOWN_RWWN;
-       }
-
-       /*
-        * TBD if this remote port is online, send a logo
-        */
-       return BFA_STATUS_OK;
-
-}
-
-/*
- *     Remote device status for display/debug.
- */
-void
-bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
-                       struct bfa_rport_attr_s *rport_attr)
-{
-       struct bfa_rport_qos_attr_s qos_attr;
-       bfa_fcs_lport_t *port = rport->port;
-       bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
-
-       memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
-
-       rport_attr->pid = rport->pid;
-       rport_attr->pwwn = rport->pwwn;
-       rport_attr->nwwn = rport->nwwn;
-       rport_attr->cos_supported = rport->fc_cos;
-       rport_attr->df_sz = rport->maxfrsize;
-       rport_attr->state = bfa_fcs_rport_get_state(rport);
-       rport_attr->fc_cos = rport->fc_cos;
-       rport_attr->cisc = rport->cisc;
-       rport_attr->scsi_function = rport->scsi_function;
-       rport_attr->curr_speed  = rport->rpf.rpsc_speed;
-       rport_attr->assigned_speed  = rport->rpf.assigned_speed;
-
-       bfa_rport_get_qos_attr(rport->bfa_rport, &qos_attr);
-       rport_attr->qos_attr = qos_attr;
-
-       rport_attr->trl_enforced = BFA_FALSE;
-       if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
-               if (rport_speed == BFA_PORT_SPEED_UNKNOWN) {
-                       /* Use default ratelim speed setting */
-                       rport_speed =
-                               bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
-               }
-
-               if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port))
-                       rport_attr->trl_enforced = BFA_TRUE;
-       }
-}
-
-/*
- *     Per remote device statistics.
- */
-void
-bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
-                       struct bfa_rport_stats_s *stats)
-{
-       *stats = rport->stats;
-}
-
-void
-bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport)
-{
-       memset((char *)&rport->stats, 0,
-                       sizeof(struct bfa_rport_stats_s));
-}
-
 struct bfa_fcs_rport_s *
 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
 {
@@ -2751,22 +2571,6 @@ bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
        return rport;
 }
 
-/*
- * This API is to set the Rport's speed. Should be used when RPSC is not
- * supported by the rport.
- */
-void
-bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport, bfa_port_speed_t speed)
-{
-       rport->rpf.assigned_speed  = speed;
-
-       /* Set this speed in f/w only if the RPSC speed is not available */
-       if (rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN)
-               bfa_rport_speed(rport->bfa_rport, speed);
-}
-
-
-
 /*
  * Remote port features (RPF) implementation.
  */
@@ -2827,7 +2631,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
        case RPFSM_EVENT_RPORT_ONLINE:
                /* Send RPSC2 to a Brocade fabric only. */
                if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
-                       ((bfa_lps_is_brcd_fabric(rport->port->fabric->lps)) ||
+                       ((rport->port->fabric->lps->brcd_switch) ||
                        (bfa_fcs_fabric_get_switch_oui(fabric) ==
                                                BFA_FCS_BRCD_SWITCH_OUI))) {
                        bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
index d8464ae60070438b01ed785d2bd667042eb1160d..1fa15edabcdd9c3032328c46ae082402d656cd25 100644 (file)
@@ -15,6 +15,7 @@
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_modules.h"
 #include "bfi_cbreg.h"
 
index b0efbc713ffe7c12a83bffe2172876d11baff9da..68077c4c4d5529494320255a36d810d6a9567e21 100644 (file)
@@ -15,6 +15,7 @@
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_modules.h"
 #include "bfi_ctreg.h"
 
index 54475b53a5ab1494490f2561fdc0c9d7884c0a55..05b0ff93284a6d440edf55b24858149fd02745c9 100644 (file)
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_ioc.h"
 #include "bfi_ctreg.h"
 #include "bfa_defs.h"
 #include "bfa_defs_svc.h"
-#include "bfad_drv.h"
 
 BFA_TRC_FILE(CNA, IOC);
 
@@ -29,7 +29,7 @@ BFA_TRC_FILE(CNA, IOC);
 #define BFA_IOC_TOV            3000    /* msecs */
 #define BFA_IOC_HWSEM_TOV      500     /* msecs */
 #define BFA_IOC_HB_TOV         500     /* msecs */
-#define BFA_IOC_HWINIT_MAX     2
+#define BFA_IOC_HWINIT_MAX     5
 #define BFA_IOC_TOV_RECOVER     BFA_IOC_HB_TOV
 
 #define bfa_ioc_timer_start(__ioc)                                     \
@@ -42,11 +42,6 @@ BFA_TRC_FILE(CNA, IOC);
                        bfa_ioc_hb_check, (__ioc), BFA_IOC_HB_TOV)
 #define bfa_hb_timer_stop(__ioc)       bfa_timer_stop(&(__ioc)->hb_timer)
 
-#define BFA_DBG_FWTRC_ENTS     (BFI_IOC_TRC_ENTS)
-#define BFA_DBG_FWTRC_LEN                                      \
-       (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) +        \
-        (sizeof(struct bfa_trc_mod_s) -                        \
-         BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
 #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
 
 /*
@@ -59,17 +54,16 @@ BFA_TRC_FILE(CNA, IOC);
                        ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
 #define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
 #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
-#define bfa_ioc_notify_hbfail(__ioc)                   \
-                       ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
-
-#ifdef BFA_IOC_IS_UEFI
-#define bfa_ioc_is_bios_optrom(__ioc) (0)
-#define bfa_ioc_is_uefi(__ioc) BFA_IOC_IS_UEFI
-#else
-#define bfa_ioc_is_bios_optrom(__ioc)  \
-       (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
-#define bfa_ioc_is_uefi(__ioc) (0)
-#endif
+#define bfa_ioc_notify_fail(__ioc)              \
+                       ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc))
+#define bfa_ioc_sync_join(__ioc)                \
+                       ((__ioc)->ioc_hwif->ioc_sync_join(__ioc))
+#define bfa_ioc_sync_leave(__ioc)               \
+                       ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc))
+#define bfa_ioc_sync_ack(__ioc)                 \
+                       ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc))
+#define bfa_ioc_sync_complete(__ioc)            \
+                       ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc))
 
 #define bfa_ioc_mbox_cmd_pending(__ioc)                \
                        (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
@@ -81,29 +75,22 @@ bfa_boolean_t bfa_auto_recover = BFA_TRUE;
  * forward declarations
  */
 static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
-static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
 static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
 static void bfa_ioc_timeout(void *ioc);
 static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
 static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
 static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
 static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
-static void bfa_ioc_hb_stop(struct bfa_ioc_s *ioc);
-static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
 static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
 static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
 static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
 static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc);
 static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
 static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
-static void bfa_ioc_pf_enabled(struct bfa_ioc_s *ioc);
-static void bfa_ioc_pf_disabled(struct bfa_ioc_s *ioc);
-static void bfa_ioc_pf_failed(struct bfa_ioc_s *ioc);
+static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc);
+static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc);
 static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
 
-/*
- *  hal_ioc_sm
- */
 
 /*
  * IOC state machine definitions/declarations
@@ -116,10 +103,11 @@ enum ioc_event {
        IOC_E_ENABLED           = 5,    /*  f/w enabled         */
        IOC_E_FWRSP_GETATTR     = 6,    /*  IOC get attribute response  */
        IOC_E_DISABLED          = 7,    /*  f/w disabled                */
-       IOC_E_FAILED            = 8,    /*  failure notice by iocpf sm  */
-       IOC_E_HBFAIL            = 9,    /*  heartbeat failure           */
-       IOC_E_HWERROR           = 10,   /*  hardware error interrupt    */
-       IOC_E_TIMEOUT           = 11,   /*  timeout                     */
+       IOC_E_INITFAILED        = 8,    /*  failure notice by iocpf sm  */
+       IOC_E_PFFAILED          = 9,    /*  failure notice by iocpf sm  */
+       IOC_E_HBFAIL            = 10,   /*  heartbeat failure           */
+       IOC_E_HWERROR           = 11,   /*  hardware error interrupt    */
+       IOC_E_TIMEOUT           = 12,   /*  timeout                     */
 };
 
 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
@@ -127,7 +115,7 @@ bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
-bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
@@ -138,7 +126,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
        {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
        {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
        {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
-       {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
+       {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL},
        {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
        {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
        {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
@@ -165,12 +153,6 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
 /*
  * Forward declareations for iocpf state machine
  */
-static void bfa_iocpf_enable(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_disable(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_fail(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_initfail(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_getattrfail(struct bfa_ioc_s *ioc);
-static void bfa_iocpf_stop(struct bfa_ioc_s *ioc);
 static void bfa_iocpf_timeout(void *ioc_arg);
 static void bfa_iocpf_sem_timeout(void *ioc_arg);
 
@@ -213,9 +195,14 @@ bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf_s, enum iocpf_event);
 bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf_s, enum iocpf_event);
 bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf_s, enum iocpf_event);
 bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf_s, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf_s,
+                                               enum iocpf_event);
 bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf_s, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf_s, enum iocpf_event);
 bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf_s, enum iocpf_event);
 bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf_s, enum iocpf_event);
+bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf_s,
+                                               enum iocpf_event);
 bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf_s, enum iocpf_event);
 
 static struct bfa_sm_table_s iocpf_sm_table[] = {
@@ -226,9 +213,12 @@ static struct bfa_sm_table_s iocpf_sm_table[] = {
        {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT},
        {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT},
        {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY},
+       {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL},
        {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL},
+       {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL},
        {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL},
        {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING},
+       {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING},
        {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
 };
 
@@ -301,7 +291,7 @@ bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
 static void
 bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
 {
-       bfa_iocpf_enable(ioc);
+       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
 }
 
 /*
@@ -318,13 +308,13 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
                bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
                break;
 
-       case IOC_E_FAILED:
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
-               break;
-
+       case IOC_E_PFFAILED:
+               /* !!! fall through !!! */
        case IOC_E_HWERROR:
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
-               bfa_iocpf_initfail(ioc);
+               ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+               if (event != IOC_E_PFFAILED)
+                       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
                break;
 
        case IOC_E_DISABLE:
@@ -333,7 +323,7 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
 
        case IOC_E_DETACH:
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
-               bfa_iocpf_stop(ioc);
+               bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
                break;
 
        case IOC_E_ENABLE:
@@ -367,18 +357,16 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
                bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
                break;
 
-       case IOC_E_FAILED:
-               bfa_ioc_timer_stop(ioc);
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
                break;
-
+       case IOC_E_PFFAILED:
        case IOC_E_HWERROR:
                bfa_ioc_timer_stop(ioc);
-               /* fall through */
-
+               /* !!! fall through !!! */
        case IOC_E_TIMEOUT:
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
-               bfa_iocpf_getattrfail(ioc);
+               ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+               if (event != IOC_E_PFFAILED)
+                       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
                break;
 
        case IOC_E_DISABLE:
@@ -402,7 +390,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
 
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
        bfa_ioc_hb_monitor(ioc);
-       BFA_LOG(KERN_INFO, bfad, log_level, "IOC enabled\n");
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
 }
 
 static void
@@ -415,22 +403,24 @@ bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
                break;
 
        case IOC_E_DISABLE:
-               bfa_ioc_hb_stop(ioc);
+               bfa_hb_timer_stop(ioc);
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
                break;
 
-       case IOC_E_FAILED:
-               bfa_ioc_hb_stop(ioc);
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
-               break;
-
+       case IOC_E_PFFAILED:
        case IOC_E_HWERROR:
-               bfa_ioc_hb_stop(ioc);
+               bfa_hb_timer_stop(ioc);
                /* !!! fall through !!! */
-
        case IOC_E_HBFAIL:
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
-               bfa_iocpf_fail(ioc);
+               bfa_ioc_fail_notify(ioc);
+
+               if (ioc->iocpf.auto_recover)
+                       bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+               else
+                       bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+
+               if (event != IOC_E_PFFAILED)
+                       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
                break;
 
        default:
@@ -443,8 +433,8 @@ static void
 bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
 {
        struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
-       bfa_iocpf_disable(ioc);
-       BFA_LOG(KERN_INFO, bfad, log_level, "IOC disabled\n");
+       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
 }
 
 /*
@@ -466,7 +456,7 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
                 * after iocpf sm completes failure processing and
                 * moves to disabled state.
                 */
-               bfa_iocpf_fail(ioc);
+               bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
                break;
 
        default:
@@ -499,7 +489,7 @@ bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
 
        case IOC_E_DETACH:
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
-               bfa_iocpf_stop(ioc);
+               bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
                break;
 
        default:
@@ -509,16 +499,16 @@ bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
 
 
 static void
-bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc)
+bfa_ioc_sm_fail_retry_entry(struct bfa_ioc_s *ioc)
 {
-       ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+       bfa_trc(ioc, 0);
 }
 
 /*
- * Hardware initialization failed.
+ * Hardware initialization retry.
  */
 static void
-bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
+bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event)
 {
        bfa_trc(ioc, event);
 
@@ -527,11 +517,21 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
                bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
                break;
 
-       case IOC_E_FAILED:
+       case IOC_E_PFFAILED:
+       case IOC_E_HWERROR:
                /*
-                * Initialization failure during iocpf init retry.
+                * Initialization retry failed.
                 */
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+               if (event != IOC_E_PFFAILED)
+                       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
+               break;
+
+       case IOC_E_INITFAILED:
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+               break;
+
+       case IOC_E_ENABLE:
                break;
 
        case IOC_E_DISABLE:
@@ -540,7 +540,7 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
 
        case IOC_E_DETACH:
                bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
-               bfa_iocpf_stop(ioc);
+               bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
                break;
 
        default:
@@ -552,21 +552,7 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
 static void
 bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
 {
-       struct list_head                        *qe;
-       struct bfa_ioc_hbfail_notify_s  *notify;
-       struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
-
-       /*
-        * Notify driver and common modules registered for notification.
-        */
-       ioc->cbfn->hbfail_cbfn(ioc->bfa);
-       list_for_each(qe, &ioc->hb_notify_q) {
-               notify = (struct bfa_ioc_hbfail_notify_s *) qe;
-               notify->cbfn(notify->cbarg);
-       }
-
-       BFA_LOG(KERN_CRIT, bfad, log_level,
-               "Heart Beat of IOC has failed\n");
+       bfa_trc(ioc, 0);
 }
 
 /*
@@ -579,23 +565,19 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
 
        switch (event) {
 
-       case IOC_E_FAILED:
-               /*
-                * Initialization failure during iocpf recovery.
-                * !!! Fall through !!!
-                */
        case IOC_E_ENABLE:
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
                break;
 
-       case IOC_E_ENABLED:
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
-               break;
-
        case IOC_E_DISABLE:
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
                break;
 
+       case IOC_E_DETACH:
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+               bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
+               break;
+
        case IOC_E_HWERROR:
                /*
                 * HB failure notification, ignore.
@@ -606,13 +588,10 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
        }
 }
 
-
-
 /*
  * IOCPF State Machine
  */
 
-
 /*
  * Reset entry actions -- initialize state machine
  */
@@ -668,22 +647,29 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        switch (event) {
        case IOCPF_E_SEMLOCKED:
                if (bfa_ioc_firmware_lock(ioc)) {
-                       iocpf->retry_count = 0;
-                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+                       if (bfa_ioc_sync_complete(ioc)) {
+                               iocpf->retry_count = 0;
+                               bfa_ioc_sync_join(ioc);
+                               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+                       } else {
+                               bfa_ioc_firmware_unlock(ioc);
+                               writel(1, ioc->ioc_regs.ioc_sem_reg);
+                               bfa_sem_timer_start(ioc);
+                       }
                } else {
-                       bfa_ioc_hw_sem_release(ioc);
+                       writel(1, ioc->ioc_regs.ioc_sem_reg);
                        bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch);
                }
                break;
 
        case IOCPF_E_DISABLE:
-               bfa_ioc_hw_sem_get_cancel(ioc);
+               bfa_sem_timer_stop(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
-               bfa_ioc_pf_disabled(ioc);
+               bfa_fsm_send_event(ioc, IOC_E_DISABLED);
                break;
 
        case IOCPF_E_STOP:
-               bfa_ioc_hw_sem_get_cancel(ioc);
+               bfa_sem_timer_stop(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
                break;
 
@@ -726,7 +712,7 @@ bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        case IOCPF_E_DISABLE:
                bfa_iocpf_timer_stop(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
-               bfa_ioc_pf_disabled(ioc);
+               bfa_fsm_send_event(ioc, IOC_E_DISABLED);
                break;
 
        case IOCPF_E_STOP:
@@ -760,13 +746,18 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
 
        switch (event) {
        case IOCPF_E_SEMLOCKED:
-               iocpf->retry_count = 0;
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+               if (bfa_ioc_sync_complete(ioc)) {
+                       bfa_ioc_sync_join(ioc);
+                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+               } else {
+                       writel(1, ioc->ioc_regs.ioc_sem_reg);
+                       bfa_sem_timer_start(ioc);
+               }
                break;
 
        case IOCPF_E_DISABLE:
-               bfa_ioc_hw_sem_get_cancel(ioc);
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+               bfa_sem_timer_stop(ioc);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
                break;
 
        default:
@@ -774,12 +765,11 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
-
 static void
 bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf)
 {
        bfa_iocpf_timer_start(iocpf->ioc);
-       bfa_ioc_reset(iocpf->ioc, BFA_FALSE);
+       bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE);
 }
 
 /*
@@ -806,23 +796,16 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
                 */
 
        case IOCPF_E_TIMEOUT:
-               iocpf->retry_count++;
-               if (iocpf->retry_count < BFA_IOC_HWINIT_MAX) {
-                       bfa_iocpf_timer_start(ioc);
-                       bfa_ioc_reset(ioc, BFA_TRUE);
-                       break;
-               }
-
-               bfa_ioc_hw_sem_release(ioc);
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
-
+               writel(1, ioc->ioc_regs.ioc_sem_reg);
                if (event == IOCPF_E_TIMEOUT)
-                       bfa_ioc_pf_failed(ioc);
+                       bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
                break;
 
        case IOCPF_E_DISABLE:
-               bfa_ioc_hw_sem_release(ioc);
                bfa_iocpf_timer_stop(ioc);
+               bfa_ioc_sync_leave(ioc);
+               writel(1, ioc->ioc_regs.ioc_sem_reg);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
                break;
 
@@ -831,7 +814,6 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
-
 static void
 bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf)
 {
@@ -853,7 +835,7 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        switch (event) {
        case IOCPF_E_FWRSP_ENABLE:
                bfa_iocpf_timer_stop(ioc);
-               bfa_ioc_hw_sem_release(ioc);
+               writel(1, ioc->ioc_regs.ioc_sem_reg);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
                break;
 
@@ -864,23 +846,15 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
                 */
 
        case IOCPF_E_TIMEOUT:
-               iocpf->retry_count++;
-               if (iocpf->retry_count < BFA_IOC_HWINIT_MAX) {
-                       writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
-                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
-                       break;
-               }
-
-               bfa_ioc_hw_sem_release(ioc);
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
-
+               writel(1, ioc->ioc_regs.ioc_sem_reg);
                if (event == IOCPF_E_TIMEOUT)
-                       bfa_ioc_pf_failed(ioc);
+                       bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
                break;
 
        case IOCPF_E_DISABLE:
                bfa_iocpf_timer_stop(ioc);
-               bfa_ioc_hw_sem_release(ioc);
+               writel(1, ioc->ioc_regs.ioc_sem_reg);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
                break;
 
@@ -893,12 +867,10 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
-
-
 static void
 bfa_iocpf_sm_ready_entry(struct bfa_iocpf_s *iocpf)
 {
-       bfa_ioc_pf_enabled(iocpf->ioc);
+       bfa_fsm_send_event(iocpf->ioc, IOC_E_ENABLED);
 }
 
 static void
@@ -914,20 +886,21 @@ bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
                break;
 
        case IOCPF_E_GETATTRFAIL:
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
                break;
 
        case IOCPF_E_FAIL:
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
                break;
 
        case IOCPF_E_FWREADY:
-               if (bfa_ioc_is_operational(ioc))
-                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
-               else
-                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
-
-               bfa_ioc_pf_failed(ioc);
+               if (bfa_ioc_is_operational(ioc)) {
+                       bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
+               } else {
+                       bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
+               }
                break;
 
        default:
@@ -935,7 +908,6 @@ bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
-
 static void
 bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf)
 {
@@ -957,7 +929,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        case IOCPF_E_FWRSP_DISABLE:
        case IOCPF_E_FWREADY:
                bfa_iocpf_timer_stop(ioc);
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
                break;
 
        case IOCPF_E_FAIL:
@@ -968,7 +940,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
 
        case IOCPF_E_TIMEOUT:
                writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
                break;
 
        case IOCPF_E_FWRSP_ENABLE:
@@ -979,13 +951,44 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
+static void
+bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf_s *iocpf)
+{
+       bfa_ioc_hw_sem_get(iocpf->ioc);
+}
+
+/**
+ * IOC hb ack request is being removed.
+ */
+static void
+bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
+{
+       struct bfa_ioc_s *ioc = iocpf->ioc;
+
+       bfa_trc(ioc, event);
+
+       switch (event) {
+       case IOCPF_E_SEMLOCKED:
+               bfa_ioc_sync_leave(ioc);
+               writel(1, ioc->ioc_regs.ioc_sem_reg);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
+               break;
+
+       case IOCPF_E_FAIL:
+               break;
+
+       default:
+               bfa_sm_fault(ioc, event);
+       }
+}
+
 /*
  * IOC disable completion entry.
  */
 static void
 bfa_iocpf_sm_disabled_entry(struct bfa_iocpf_s *iocpf)
 {
-       bfa_ioc_pf_disabled(iocpf->ioc);
+       bfa_fsm_send_event(iocpf->ioc, IOC_E_DISABLED);
 }
 
 static void
@@ -997,6 +1000,7 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
 
        switch (event) {
        case IOCPF_E_ENABLE:
+               iocpf->retry_count = 0;
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
                break;
 
@@ -1010,11 +1014,65 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
+static void
+bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf)
+{
+       bfa_ioc_hw_sem_get(iocpf->ioc);
+}
+
+/**
+ * @brief
+ * Hardware initialization failed.
+ */
+static void
+bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
+{
+       struct bfa_ioc_s *ioc = iocpf->ioc;
+
+       bfa_trc(ioc, event);
+
+       switch (event) {
+       case IOCPF_E_SEMLOCKED:
+               bfa_ioc_notify_fail(ioc);
+               bfa_ioc_sync_ack(ioc);
+               iocpf->retry_count++;
+               if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) {
+                       bfa_ioc_sync_leave(ioc);
+                       writel(1, ioc->ioc_regs.ioc_sem_reg);
+                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
+               } else {
+                       if (bfa_ioc_sync_complete(ioc))
+                               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+                       else {
+                               writel(1, ioc->ioc_regs.ioc_sem_reg);
+                               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
+                       }
+               }
+               break;
+
+       case IOCPF_E_DISABLE:
+               bfa_sem_timer_stop(ioc);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
+               break;
+
+       case IOCPF_E_STOP:
+               bfa_sem_timer_stop(ioc);
+               bfa_ioc_firmware_unlock(ioc);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
+               break;
+
+       case IOCPF_E_FAIL:
+               break;
+
+       default:
+               bfa_sm_fault(ioc, event);
+       }
+}
 
 static void
 bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
 {
-       bfa_iocpf_timer_start(iocpf->ioc);
+       bfa_fsm_send_event(iocpf->ioc, IOC_E_INITFAILED);
 }
 
 /*
@@ -1029,47 +1087,77 @@ bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
 
        switch (event) {
        case IOCPF_E_DISABLE:
-               bfa_iocpf_timer_stop(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
                break;
 
        case IOCPF_E_STOP:
-               bfa_iocpf_timer_stop(ioc);
                bfa_ioc_firmware_unlock(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
                break;
 
-       case IOCPF_E_TIMEOUT:
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
-               break;
-
        default:
                bfa_sm_fault(ioc, event);
        }
 }
 
-
 static void
-bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
+bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf_s *iocpf)
 {
-       /*
+       /**
         * Mark IOC as failed in hardware and stop firmware.
         */
        bfa_ioc_lpu_stop(iocpf->ioc);
-       writel(BFI_IOC_FAIL, iocpf->ioc->ioc_regs.ioc_fwstate);
 
-       /*
-        * Notify other functions on HB failure.
-        */
-       bfa_ioc_notify_hbfail(iocpf->ioc);
-
-       /*
+       /**
         * Flush any queued up mailbox requests.
         */
        bfa_ioc_mbox_hbfail(iocpf->ioc);
 
-       if (iocpf->auto_recover)
-               bfa_iocpf_recovery_timer_start(iocpf->ioc);
+       bfa_ioc_hw_sem_get(iocpf->ioc);
+}
+
+static void
+bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
+{
+       struct bfa_ioc_s *ioc = iocpf->ioc;
+
+       bfa_trc(ioc, event);
+
+       switch (event) {
+       case IOCPF_E_SEMLOCKED:
+               iocpf->retry_count = 0;
+               bfa_ioc_sync_ack(ioc);
+               bfa_ioc_notify_fail(ioc);
+               if (!iocpf->auto_recover) {
+                       bfa_ioc_sync_leave(ioc);
+                       writel(1, ioc->ioc_regs.ioc_sem_reg);
+                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+               } else {
+                       if (bfa_ioc_sync_complete(ioc))
+                               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
+                       else {
+                               writel(1, ioc->ioc_regs.ioc_sem_reg);
+                               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
+                       }
+               }
+               break;
+
+       case IOCPF_E_DISABLE:
+               bfa_sem_timer_stop(ioc);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
+               break;
+
+       case IOCPF_E_FAIL:
+               break;
+
+       default:
+               bfa_sm_fault(ioc, event);
+       }
+}
+
+static void
+bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
+{
 }
 
 /*
@@ -1084,24 +1172,16 @@ bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
 
        switch (event) {
        case IOCPF_E_DISABLE:
-               if (iocpf->auto_recover)
-                       bfa_iocpf_timer_stop(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
                break;
 
-       case IOCPF_E_TIMEOUT:
-               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
-               break;
-
        default:
                bfa_sm_fault(ioc, event);
        }
 }
 
-
-
 /*
- *  hal_ioc_pvt BFA IOC private functions
+ *  BFA IOC private functions
  */
 
 static void
@@ -1143,12 +1223,6 @@ bfa_ioc_sem_get(void __iomem *sem_reg)
        return BFA_FALSE;
 }
 
-void
-bfa_ioc_sem_release(void __iomem *sem_reg)
-{
-       writel(1, sem_reg);
-}
-
 static void
 bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
 {
@@ -1167,18 +1241,6 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
        bfa_sem_timer_start(ioc);
 }
 
-void
-bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
-{
-       writel(1, ioc->ioc_regs.ioc_sem_reg);
-}
-
-static void
-bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc)
-{
-       bfa_sem_timer_stop(ioc);
-}
-
 /*
  * Initialize LPU local memory (aka secondary memory / SRAM)
  */
@@ -1258,8 +1320,8 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
        int             i;
        u32     *fwsig = (u32 *) fwhdr;
 
-       pgnum = bfa_ioc_smem_pgnum(ioc, loff);
-       pgoff = bfa_ioc_smem_pgoff(ioc, loff);
+       pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
+       pgoff = PSS_SMEM_PGOFF(loff);
        writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
        for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
@@ -1342,7 +1404,6 @@ bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
                writel(1, ioc->ioc_regs.lpu_mbox_cmd);
 }
 
-
 static void
 bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
 {
@@ -1465,12 +1526,12 @@ static void
 bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
 {
        struct bfi_ioc_ctrl_req_s enable_req;
-       struct bfa_timeval_s tv;
+       struct timeval tv;
 
        bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
                    bfa_ioc_portid(ioc));
        enable_req.ioc_class = ioc->ioc_mc;
-       bfa_os_gettimeofday(&tv);
+       do_gettimeofday(&tv);
        enable_req.tv_sec = be32_to_cpu(tv.tv_sec);
        bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
 }
@@ -1504,7 +1565,6 @@ bfa_ioc_hb_check(void *cbarg)
 
        hb_count = readl(ioc->ioc_regs.heartbeat);
        if (ioc->hb_count == hb_count) {
-               printk(KERN_CRIT "Firmware heartbeat failure at %d", hb_count);
                bfa_ioc_recover(ioc);
                return;
        } else {
@@ -1522,13 +1582,6 @@ bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
        bfa_hb_timer_start(ioc);
 }
 
-static void
-bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
-{
-       bfa_hb_timer_stop(ioc);
-}
-
-
 /*
  *     Initiate a full firmware download.
  */
@@ -1550,8 +1603,8 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
        bfa_trc(ioc, bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)));
        fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
 
-       pgnum = bfa_ioc_smem_pgnum(ioc, loff);
-       pgoff = bfa_ioc_smem_pgoff(ioc, loff);
+       pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
+       pgoff = PSS_SMEM_PGOFF(loff);
 
        writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
@@ -1581,7 +1634,8 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
                }
        }
 
-       writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
+       writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
+                       ioc->ioc_regs.host_page_num_fn);
 
        /*
         * Set boot type and boot param at the end.
@@ -1592,11 +1646,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
                        swab32(boot_env));
 }
 
-static void
-bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force)
-{
-       bfa_ioc_hwinit(ioc, force);
-}
 
 /*
  * Update BFA configuration from firmware configuration.
@@ -1683,12 +1732,13 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
 static bfa_status_t
 bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
 {
-       u32 pgnum, loff, r32;
+       u32 pgnum, loff;
+       __be32 r32;
        int i, len;
        u32 *buf = tbuf;
 
-       pgnum = bfa_ioc_smem_pgnum(ioc, soff);
-       loff = bfa_ioc_smem_pgoff(ioc, soff);
+       pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
+       loff = PSS_SMEM_PGOFF(soff);
        bfa_trc(ioc, pgnum);
        bfa_trc(ioc, loff);
        bfa_trc(ioc, sz);
@@ -1719,11 +1769,12 @@ bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
                        writel(pgnum, ioc->ioc_regs.host_page_num_fn);
                }
        }
-       writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
+       writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
+                       ioc->ioc_regs.host_page_num_fn);
        /*
         *  release semaphore.
         */
-       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+       writel(1, ioc->ioc_regs.ioc_init_sem_reg);
 
        bfa_trc(ioc, pgnum);
        return BFA_STATUS_OK;
@@ -1742,8 +1793,8 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
        int i, len;
        u32 pgnum, loff;
 
-       pgnum = bfa_ioc_smem_pgnum(ioc, soff);
-       loff = bfa_ioc_smem_pgoff(ioc, soff);
+       pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
+       loff = PSS_SMEM_PGOFF(soff);
        bfa_trc(ioc, pgnum);
        bfa_trc(ioc, loff);
        bfa_trc(ioc, sz);
@@ -1773,35 +1824,38 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
                        writel(pgnum, ioc->ioc_regs.host_page_num_fn);
                }
        }
-       writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
+       writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
+                       ioc->ioc_regs.host_page_num_fn);
 
        /*
         *  release semaphore.
         */
-       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+       writel(1, ioc->ioc_regs.ioc_init_sem_reg);
        bfa_trc(ioc, pgnum);
        return BFA_STATUS_OK;
 }
 
-/*
- * hal iocpf to ioc interface
- */
 static void
-bfa_ioc_pf_enabled(struct bfa_ioc_s *ioc)
+bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
 {
-       bfa_fsm_send_event(ioc, IOC_E_ENABLED);
-}
+       struct list_head                *qe;
+       struct bfa_ioc_hbfail_notify_s  *notify;
+       struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
 
-static void
-bfa_ioc_pf_disabled(struct bfa_ioc_s *ioc)
-{
-       bfa_fsm_send_event(ioc, IOC_E_DISABLED);
-}
+       /**
+        * Notify driver and common modules registered for notification.
+        */
+       ioc->cbfn->hbfail_cbfn(ioc->bfa);
+       list_for_each(qe, &ioc->hb_notify_q) {
+               notify = (struct bfa_ioc_hbfail_notify_s *) qe;
+               notify->cbfn(notify->cbarg);
+       }
+
+       bfa_ioc_debug_save_ftrc(ioc);
+
+       BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
+               "Heart Beat of IOC has failed\n");
 
-static void
-bfa_ioc_pf_failed(struct bfa_ioc_s *ioc)
-{
-       bfa_fsm_send_event(ioc, IOC_E_FAILED);
 }
 
 static void
@@ -1812,17 +1866,11 @@ bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
         * Provide enable completion callback.
         */
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
-       BFA_LOG(KERN_WARNING, bfad, log_level,
+       BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
                "Running firmware version is incompatible "
                "with the driver version\n");
 }
 
-
-
-/*
- *  hal_ioc_public
- */
-
 bfa_status_t
 bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
 {
@@ -1838,7 +1886,7 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
        /*
         *  release semaphore.
         */
-       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+       writel(1, ioc->ioc_regs.ioc_init_sem_reg);
 
        return BFA_STATUS_OK;
 }
@@ -1909,7 +1957,7 @@ bfa_ioc_is_initialized(struct bfa_ioc_s *ioc)
 void
 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
 {
-       u32     *msgp = mbmsg;
+       __be32  *msgp = mbmsg;
        u32     r32;
        int             i;
 
@@ -2043,15 +2091,6 @@ bfa_ioc_mem_claim(struct bfa_ioc_s *ioc,  u8 *dm_kva, u64 dm_pa)
        ioc->attr = (struct bfi_ioc_attr_s *) dm_kva;
 }
 
-/*
- * Return size of dma memory required.
- */
-u32
-bfa_ioc_meminfo(void)
-{
-       return BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
-}
-
 void
 bfa_ioc_enable(struct bfa_ioc_s *ioc)
 {
@@ -2068,18 +2107,6 @@ bfa_ioc_disable(struct bfa_ioc_s *ioc)
        bfa_fsm_send_event(ioc, IOC_E_DISABLE);
 }
 
-/*
- * Returns memory required for saving firmware trace in case of crash.
- * Driver must call this interface to allocate memory required for
- * automatic saving of firmware trace. Driver should call
- * bfa_ioc_debug_memclaim() right after bfa_ioc_attach() to setup this
- * trace memory.
- */
-int
-bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover)
-{
-       return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
-}
 
 /*
  * Initialize memory for saving firmware trace. Driver must initialize
@@ -2089,19 +2116,7 @@ void
 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
 {
        ioc->dbg_fwsave     = dbg_fwsave;
-       ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->iocpf.auto_recover);
-}
-
-u32
-bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr)
-{
-       return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
-}
-
-u32
-bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr)
-{
-       return PSS_SMEM_PGOFF(fmaddr);
+       ioc->dbg_fwsave_len = (ioc->iocpf.auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
 }
 
 /*
@@ -2264,15 +2279,14 @@ bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
        return BFA_TRUE;
 }
 
-/*
- * Add to IOC heartbeat failure notification queue. To be used by common
- * modules such as cee, port, diag.
+/**
+ * Reset IOC fwstate registers.
  */
 void
-bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
-                       struct bfa_ioc_hbfail_notify_s *notify)
+bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc)
 {
-       list_add_tail(&notify->qe, &ioc->hb_notify_q);
+       writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+       writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
 }
 
 #define BFA_MFG_NAME "Brocade"
@@ -2306,7 +2320,7 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
        else
                ad_attr->prototype = 0;
 
-       ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
+       ad_attr->pwwn = ioc->attr->pwwn;
        ad_attr->mac  = bfa_ioc_get_mac(ioc);
 
        ad_attr->pcie_gen = ioc_attr->pcie_gen;
@@ -2317,7 +2331,8 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
        bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
 
        ad_attr->cna_capable = ioc->cna;
-       ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna;
+       ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna &&
+                               !ad_attr->is_mezz;
 }
 
 enum bfa_ioc_type_e
@@ -2455,27 +2470,6 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
        bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
 }
 
-/*
- *  hal_wwn_public
- */
-wwn_t
-bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc)
-{
-       return ioc->attr->pwwn;
-}
-
-wwn_t
-bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc)
-{
-       return ioc->attr->nwwn;
-}
-
-u64
-bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
-{
-       return ioc->attr->mfg_pwwn;
-}
-
 mac_t
 bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
 {
@@ -2488,18 +2482,6 @@ bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
                return ioc->attr->mac;
 }
 
-wwn_t
-bfa_ioc_get_mfg_pwwn(struct bfa_ioc_s *ioc)
-{
-       return ioc->attr->mfg_pwwn;
-}
-
-wwn_t
-bfa_ioc_get_mfg_nwwn(struct bfa_ioc_s *ioc)
-{
-       return ioc->attr->mfg_nwwn;
-}
-
 mac_t
 bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
 {
@@ -2541,14 +2523,6 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
        return BFA_STATUS_OK;
 }
 
-/*
- * Clear saved firmware trace
- */
-void
-bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc)
-{
-       ioc->dbg_fwsave_once = BFA_TRUE;
-}
 
 /*
  * Retrieve saved firmware trace from a prior IOC failure.
@@ -2701,13 +2675,16 @@ bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
  * Save firmware trace if configured.
  */
 static void
-bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
+bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc)
 {
        int             tlen;
 
-       if (ioc->dbg_fwsave_len) {
-               tlen = ioc->dbg_fwsave_len;
-               bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
+       if (ioc->dbg_fwsave_once) {
+               ioc->dbg_fwsave_once = BFA_FALSE;
+               if (ioc->dbg_fwsave_len) {
+                       tlen = ioc->dbg_fwsave_len;
+                       bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
+               }
        }
 }
 
@@ -2717,11 +2694,6 @@ bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
 static void
 bfa_ioc_recover(struct bfa_ioc_s *ioc)
 {
-       if (ioc->dbg_fwsave_once) {
-               ioc->dbg_fwsave_once = BFA_FALSE;
-               bfa_ioc_debug_save(ioc);
-       }
-
        bfa_ioc_stats(ioc, ioc_hbfails);
        bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
 }
@@ -2734,45 +2706,8 @@ bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc)
 }
 
 /*
- *  hal_iocpf_pvt BFA IOC PF private functions
+ *  BFA IOC PF private functions
  */
-
-static void
-bfa_iocpf_enable(struct bfa_ioc_s *ioc)
-{
-       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
-}
-
-static void
-bfa_iocpf_disable(struct bfa_ioc_s *ioc)
-{
-       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
-}
-
-static void
-bfa_iocpf_fail(struct bfa_ioc_s *ioc)
-{
-       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
-}
-
-static void
-bfa_iocpf_initfail(struct bfa_ioc_s *ioc)
-{
-       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
-}
-
-static void
-bfa_iocpf_getattrfail(struct bfa_ioc_s *ioc)
-{
-       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
-}
-
-static void
-bfa_iocpf_stop(struct bfa_ioc_s *ioc)
-{
-       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
-}
-
 static void
 bfa_iocpf_timeout(void *ioc_arg)
 {
@@ -2793,12 +2728,6 @@ bfa_iocpf_sem_timeout(void *ioc_arg)
 /*
  *  bfa timer function
  */
-void
-bfa_timer_init(struct bfa_timer_mod_s *mod)
-{
-       INIT_LIST_HEAD(&mod->timer_q);
-}
-
 void
 bfa_timer_beat(struct bfa_timer_mod_s *mod)
 {
index 9c407a87a1a1e01e228531c5dd48a4a0f1c85f3b..5d2f34290e9dc58c56b3de13457022221953090c 100644 (file)
 #ifndef __BFA_IOC_H__
 #define __BFA_IOC_H__
 
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 #include "bfa_cs.h"
 #include "bfi.h"
 
+#define BFA_DBG_FWTRC_ENTS     (BFI_IOC_TRC_ENTS)
+#define BFA_DBG_FWTRC_LEN                                      \
+       (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) +        \
+       (sizeof(struct bfa_trc_mod_s) -                         \
+       BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
 /*
  * BFA timer declarations
  */
@@ -47,7 +52,6 @@ struct bfa_timer_mod_s {
 #define BFA_TIMER_FREQ 200 /* specified in millisecs */
 
 void bfa_timer_beat(struct bfa_timer_mod_s *mod);
-void bfa_timer_init(struct bfa_timer_mod_s *mod);
 void bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
                        bfa_timer_cbfn_t timercb, void *arg,
                        unsigned int timeout);
@@ -70,7 +74,7 @@ struct bfa_sge_s {
 #define bfa_swap_words(_x)  (  \
        ((_x) << 32) | ((_x) >> 32))
 
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
 #define bfa_sge_to_be(_x)
 #define bfa_sge_to_le(_x)      bfa_sge_word_swap(_x)
 #define bfa_sgaddr_le(_x)      bfa_swap_words(_x)
@@ -115,8 +119,8 @@ struct bfa_dma_s {
 static inline void
 __bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
 {
-       dma_addr->a32.addr_lo = (u32) pa;
-       dma_addr->a32.addr_hi = (u32) (bfa_os_u32(pa));
+       dma_addr->a32.addr_lo = (__be32) pa;
+       dma_addr->a32.addr_hi = (__be32) (pa >> 32);
 }
 
 
@@ -125,8 +129,8 @@ __bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
 static inline void
 __bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
 {
-       dma_addr->a32.addr_lo = (u32) cpu_to_be32(pa);
-       dma_addr->a32.addr_hi = (u32) cpu_to_be32(bfa_os_u32(pa));
+       dma_addr->a32.addr_lo = cpu_to_be32(pa);
+       dma_addr->a32.addr_hi = cpu_to_be32(pa >> 32);
 }
 
 struct bfa_ioc_regs_s {
@@ -145,8 +149,11 @@ struct bfa_ioc_regs_s {
        void __iomem *host_page_num_fn;
        void __iomem *heartbeat;
        void __iomem *ioc_fwstate;
+       void __iomem *alt_ioc_fwstate;
        void __iomem *ll_halt;
+       void __iomem *alt_ll_halt;
        void __iomem *err_set;
+       void __iomem *ioc_fail_sync;
        void __iomem *shirq_isr_next;
        void __iomem *shirq_msk_next;
        void __iomem *smem_page_start;
@@ -254,8 +261,12 @@ struct bfa_ioc_hwif_s {
        void            (*ioc_map_port) (struct bfa_ioc_s *ioc);
        void            (*ioc_isr_mode_set)     (struct bfa_ioc_s *ioc,
                                        bfa_boolean_t msix);
-       void            (*ioc_notify_hbfail)    (struct bfa_ioc_s *ioc);
+       void            (*ioc_notify_fail)      (struct bfa_ioc_s *ioc);
        void            (*ioc_ownership_reset)  (struct bfa_ioc_s *ioc);
+       void            (*ioc_sync_join)        (struct bfa_ioc_s *ioc);
+       void            (*ioc_sync_leave)       (struct bfa_ioc_s *ioc);
+       void            (*ioc_sync_ack)         (struct bfa_ioc_s *ioc);
+       bfa_boolean_t   (*ioc_sync_complete)    (struct bfa_ioc_s *ioc);
 };
 
 #define bfa_ioc_pcifn(__ioc)           ((__ioc)->pcidev.pci_func)
@@ -285,6 +296,15 @@ struct bfa_ioc_hwif_s {
 #define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off)     (off % BFI_FLASH_CHUNK_SZ_WORDS)
 #define BFA_IOC_FLASH_CHUNK_ADDR(chunkno)  (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
 
+#ifdef BFA_IOC_IS_UEFI
+#define bfa_ioc_is_bios_optrom(__ioc) (0)
+#define bfa_ioc_is_uefi(__ioc) BFA_IOC_IS_UEFI
+#else
+#define bfa_ioc_is_bios_optrom(__ioc)   \
+       (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
+#define bfa_ioc_is_uefi(__ioc) (0)
+#endif
+
 /*
  * IOC mailbox interface
  */
@@ -325,7 +345,6 @@ void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
 void bfa_ioc_detach(struct bfa_ioc_s *ioc);
 void bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
                enum bfi_mclass mc);
-u32 bfa_ioc_meminfo(void);
 void bfa_ioc_mem_claim(struct bfa_ioc_s *ioc,  u8 *dm_kva, u64 dm_pa);
 void bfa_ioc_enable(struct bfa_ioc_s *ioc);
 void bfa_ioc_disable(struct bfa_ioc_s *ioc);
@@ -340,6 +359,7 @@ bfa_boolean_t bfa_ioc_is_initialized(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
+void bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc);
 enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc);
 void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num);
 void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver);
@@ -353,24 +373,16 @@ enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc);
 void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
 void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
                struct bfa_adapter_attr_s *ad_attr);
-int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover);
 void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
 bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
                int *trclen);
-void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc);
 bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
                                 int *trclen);
 bfa_status_t bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
        u32 *offset, int *buflen);
-u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
-u32 bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr);
 void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
-void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
-       struct bfa_ioc_hbfail_notify_s *notify);
 bfa_boolean_t bfa_ioc_sem_get(void __iomem *sem_reg);
-void bfa_ioc_sem_release(void __iomem *sem_reg);
-void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
 void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
                        struct bfi_ioc_image_hdr_s *fwhdr);
 bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
@@ -381,13 +393,8 @@ bfa_status_t bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc);
 /*
  * bfa mfg wwn API functions
  */
-wwn_t bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc);
-wwn_t bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc);
 mac_t bfa_ioc_get_mac(struct bfa_ioc_s *ioc);
-wwn_t bfa_ioc_get_mfg_pwwn(struct bfa_ioc_s *ioc);
-wwn_t bfa_ioc_get_mfg_nwwn(struct bfa_ioc_s *ioc);
 mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc);
-u64 bfa_ioc_get_adid(struct bfa_ioc_s *ioc);
 
 /*
  * F/W Image Size & Chunk
@@ -421,7 +428,7 @@ bfa_cb_image_get_chunk(int type, u32 off)
                return bfi_image_ct_cna_get_chunk(off); break;
        case BFI_IMAGE_CB_FC:
                return bfi_image_cb_fc_get_chunk(off);  break;
-       default: return 0;
+       default: return NULL;
        }
 }
 
index 909945043850fbbeaf5b3a0699fd46e11186bd9e..788ecca5aa01e2a427a75b2009b6cd3e6e0bf4b1 100644 (file)
@@ -15,6 +15,7 @@
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_ioc.h"
 #include "bfi_cbreg.h"
 #include "bfa_defs.h"
@@ -29,10 +30,14 @@ static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
-static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc);
 
-struct bfa_ioc_hwif_s hwif_cb;
+static struct bfa_ioc_hwif_s hwif_cb;
 
 /*
  * Called from bfa_ioc_attach() to map asic specific calls.
@@ -46,18 +51,38 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
        hwif_cb.ioc_reg_init = bfa_ioc_cb_reg_init;
        hwif_cb.ioc_map_port = bfa_ioc_cb_map_port;
        hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set;
-       hwif_cb.ioc_notify_hbfail = bfa_ioc_cb_notify_hbfail;
+       hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail;
        hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset;
+       hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join;
+       hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave;
+       hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack;
+       hwif_cb.ioc_sync_complete = bfa_ioc_cb_sync_complete;
 
        ioc->ioc_hwif = &hwif_cb;
 }
 
-/*
+/**
  * Return true if firmware of current driver matches the running firmware.
  */
 static bfa_boolean_t
 bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
 {
+       struct bfi_ioc_image_hdr_s fwhdr;
+       uint32_t fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+       if ((fwstate == BFI_IOC_UNINIT) || bfa_ioc_is_uefi(ioc) ||
+                               bfa_ioc_is_bios_optrom(ioc))
+               return BFA_TRUE;
+
+       bfa_ioc_fwver_get(ioc, &fwhdr);
+
+       if (swab32(fwhdr.exec) == BFI_BOOT_TYPE_NORMAL)
+               return BFA_TRUE;
+
+       bfa_trc(ioc, fwstate);
+       bfa_trc(ioc, fwhdr.exec);
+       writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+
        return BFA_TRUE;
 }
 
@@ -70,7 +95,7 @@ bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
  * Notify other functions on HB failure.
  */
 static void
-bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
+bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc)
 {
        writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
        readl(ioc->ioc_regs.err_set);
@@ -108,9 +133,11 @@ bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
        if (ioc->port_id == 0) {
                ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
                ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+               ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG;
        } else {
                ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
                ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+               ioc->ioc_regs.alt_ioc_fwstate = (rb + BFA_IOC0_STATE_REG);
        }
 
        /*
@@ -181,10 +208,71 @@ bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
         * will lock it instead of clearing it.
         */
        readl(ioc->ioc_regs.ioc_sem_reg);
-       bfa_ioc_hw_sem_release(ioc);
+       writel(1, ioc->ioc_regs.ioc_sem_reg);
 }
 
+/**
+ * Synchronized IOC failure processing routines
+ */
+static void
+bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc)
+{
+}
 
+static void
+bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc)
+{
+}
+
+static void
+bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc)
+{
+       writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+}
+
+static bfa_boolean_t
+bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc)
+{
+       uint32_t fwstate, alt_fwstate;
+       fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+       /**
+        * At this point, this IOC is hoding the hw sem in the
+        * start path (fwcheck) OR in the disable/enable path
+        * OR to check if the other IOC has acknowledged failure.
+        *
+        * So, this IOC can be in UNINIT, INITING, DISABLED, FAIL
+        * or in MEMTEST states. In a normal scenario, this IOC
+        * can not be in OP state when this function is called.
+        *
+        * However, this IOC could still be in OP state when
+        * the OS driver is starting up, if the OptROM code has
+        * left it in that state.
+        *
+        * If we had marked this IOC's fwstate as BFI_IOC_FAIL
+        * in the failure case and now, if the fwstate is not
+        * BFI_IOC_FAIL it implies that the other PCI fn have
+        * reinitialized the ASIC or this IOC got disabled, so
+        * return TRUE.
+        */
+       if (fwstate == BFI_IOC_UNINIT ||
+               fwstate == BFI_IOC_INITING ||
+               fwstate == BFI_IOC_DISABLED ||
+               fwstate == BFI_IOC_MEMTEST ||
+               fwstate == BFI_IOC_OP)
+               return BFA_TRUE;
+       else {
+               alt_fwstate = readl(ioc->ioc_regs.alt_ioc_fwstate);
+               if (alt_fwstate == BFI_IOC_FAIL ||
+                       alt_fwstate == BFI_IOC_DISABLED ||
+                       alt_fwstate == BFI_IOC_UNINIT ||
+                       alt_fwstate == BFI_IOC_INITING ||
+                       alt_fwstate == BFI_IOC_MEMTEST)
+                       return BFA_TRUE;
+               else
+                       return BFA_FALSE;
+       }
+}
 
 bfa_status_t
 bfa_ioc_cb_pll_init(void __iomem *rb, bfa_boolean_t fcmode)
index 115730c0aa77f321aa25ee6f0d7136f43c8c2b90..9da55a836bfb23f14123d6fcdfa7bec4d98b1149 100644 (file)
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_ioc.h"
 #include "bfi_ctreg.h"
 #include "bfa_defs.h"
 
 BFA_TRC_FILE(CNA, IOC_CT);
 
+#define bfa_ioc_ct_sync_pos(__ioc)      \
+               ((uint32_t) (1 << bfa_ioc_pcifn(__ioc)))
+#define BFA_IOC_SYNC_REQD_SH    16
+#define bfa_ioc_ct_get_sync_ackd(__val) (__val & 0x0000ffff)
+#define bfa_ioc_ct_clear_sync_ackd(__val)       (__val & 0xffff0000)
+#define bfa_ioc_ct_get_sync_reqd(__val) (__val >> BFA_IOC_SYNC_REQD_SH)
+#define bfa_ioc_ct_sync_reqd_pos(__ioc) \
+                       (bfa_ioc_ct_sync_pos(__ioc) << BFA_IOC_SYNC_REQD_SH)
+
 /*
  * forward declarations
  */
@@ -29,10 +39,14 @@ static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
-static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc);
 
-struct bfa_ioc_hwif_s hwif_ct;
+static struct bfa_ioc_hwif_s hwif_ct;
 
 /*
  * Called from bfa_ioc_attach() to map asic specific calls.
@@ -46,8 +60,12 @@ bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
        hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
        hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
        hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
-       hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail;
+       hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail;
        hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
+       hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join;
+       hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave;
+       hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack;
+       hwif_ct.ioc_sync_complete = bfa_ioc_ct_sync_complete;
 
        ioc->ioc_hwif = &hwif_ct;
 }
@@ -83,7 +101,8 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
         */
        if (usecnt == 0) {
                writel(1, ioc->ioc_regs.ioc_usage_reg);
-               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+               writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
+               writel(0, ioc->ioc_regs.ioc_fail_sync);
                bfa_trc(ioc, usecnt);
                return BFA_TRUE;
        }
@@ -101,7 +120,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
         */
        bfa_ioc_fwver_get(ioc, &fwhdr);
        if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
-               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+               writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
                bfa_trc(ioc, usecnt);
                return BFA_FALSE;
        }
@@ -111,7 +130,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
         */
        usecnt++;
        writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
-       bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+       writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
        bfa_trc(ioc, usecnt);
        return BFA_TRUE;
 }
@@ -145,19 +164,21 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
        writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
        bfa_trc(ioc, usecnt);
 
-       bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+       writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
 }
 
 /*
  * Notify other functions on HB failure.
  */
 static void
-bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
+bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc)
 {
        if (ioc->cna) {
                writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
+               writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt);
                /* Wait for halt to take effect */
                readl(ioc->ioc_regs.ll_halt);
+               readl(ioc->ioc_regs.alt_ll_halt);
        } else {
                writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
                readl(ioc->ioc_regs.err_set);
@@ -209,15 +230,19 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
        if (ioc->port_id == 0) {
                ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
                ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+               ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG;
                ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
                ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
                ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
+               ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1;
        } else {
                ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
                ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+               ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_STATE_REG;
                ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
                ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
                ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
+               ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0;
        }
 
        /*
@@ -235,6 +260,7 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
        ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
        ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
        ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
+       ioc->ioc_regs.ioc_fail_sync = (rb + BFA_IOC_FAIL_SYNC);
 
        /*
         * sram memory access
@@ -313,7 +339,7 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
        if (ioc->cna) {
                bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
                writel(0, ioc->ioc_regs.ioc_usage_reg);
-               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+               writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
        }
 
        /*
@@ -322,10 +348,80 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
         * will lock it instead of clearing it.
         */
        readl(ioc->ioc_regs.ioc_sem_reg);
-       bfa_ioc_hw_sem_release(ioc);
+       writel(1, ioc->ioc_regs.ioc_sem_reg);
 }
 
+/**
+ * Synchronized IOC failure processing routines
+ */
+static void
+bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc)
+{
+       uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+       uint32_t sync_pos = bfa_ioc_ct_sync_reqd_pos(ioc);
+
+       writel((r32 | sync_pos), ioc->ioc_regs.ioc_fail_sync);
+}
 
+static void
+bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc)
+{
+       uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+       uint32_t sync_msk = bfa_ioc_ct_sync_reqd_pos(ioc) |
+                                       bfa_ioc_ct_sync_pos(ioc);
+
+       writel((r32 & ~sync_msk), ioc->ioc_regs.ioc_fail_sync);
+}
+
+static void
+bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc)
+{
+       uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+
+       writel((r32 | bfa_ioc_ct_sync_pos(ioc)),
+               ioc->ioc_regs.ioc_fail_sync);
+}
+
+static bfa_boolean_t
+bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc)
+{
+       uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+       uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32);
+       uint32_t sync_ackd = bfa_ioc_ct_get_sync_ackd(r32);
+       uint32_t tmp_ackd;
+
+       if (sync_ackd == 0)
+               return BFA_TRUE;
+
+       /**
+        * The check below is to see whether any other PCI fn
+        * has reinitialized the ASIC (reset sync_ackd bits)
+        * and failed again while this IOC was waiting for hw
+        * semaphore (in bfa_iocpf_sm_semwait()).
+        */
+       tmp_ackd = sync_ackd;
+       if ((sync_reqd &  bfa_ioc_ct_sync_pos(ioc)) &&
+               !(sync_ackd & bfa_ioc_ct_sync_pos(ioc)))
+               sync_ackd |= bfa_ioc_ct_sync_pos(ioc);
+
+       if (sync_reqd == sync_ackd) {
+               writel(bfa_ioc_ct_clear_sync_ackd(r32),
+                       ioc->ioc_regs.ioc_fail_sync);
+               writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+               writel(BFI_IOC_FAIL, ioc->ioc_regs.alt_ioc_fwstate);
+               return BFA_TRUE;
+       }
+
+       /**
+        * If another PCI fn reinitialized and failed again while
+        * this IOC was waiting for hw sem, the sync_ackd bit for
+        * this IOC need to be set again to allow reinitialization.
+        */
+       if (tmp_ackd != sync_ackd)
+               writel((r32 | sync_ackd), ioc->ioc_regs.ioc_fail_sync);
+
+       return BFA_FALSE;
+}
 
 /*
  * Check the firmware state to know if pll_init has been completed already
index 15407ab39e77759e3cafa96214636b19c2fc22bc..ab79ff6fdeea6b8c7bc1c6f3b2b88af142e1f5fb 100644 (file)
@@ -99,7 +99,6 @@ struct bfa_module_s {
        void (*iocdisable) (struct bfa_s *bfa);
 };
 
-extern struct bfa_module_s *hal_mods[];
 
 struct bfa_s {
        void                    *bfad;          /*  BFA driver instance    */
@@ -116,8 +115,6 @@ struct bfa_s {
        struct bfa_msix_s       msix;
 };
 
-extern bfa_isr_func_t bfa_isrs[BFI_MC_MAX];
-extern bfa_ioc_mbox_mcfunc_t  bfa_mbox_isrs[];
 extern bfa_boolean_t bfa_auto_recover;
 extern struct bfa_module_s hal_mod_sgpg;
 extern struct bfa_module_s hal_mod_fcport;
diff --git a/drivers/scsi/bfa/bfa_os_inc.h b/drivers/scsi/bfa/bfa_os_inc.h
deleted file mode 100644 (file)
index 65df62e..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-
-#ifndef __BFA_OS_INC_H__
-#define __BFA_OS_INC_H__
-
-#include <linux/types.h>
-#include <linux/version.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/idr.h>
-#include <linux/interrupt.h>
-#include <linux/cdev.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-#include <linux/workqueue.h>
-#include <linux/bitops.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi_transport_fc.h>
-#include <scsi/scsi_transport.h>
-
-#ifdef __BIG_ENDIAN
-#define __BIGENDIAN
-#endif
-
-static inline u64 bfa_os_get_log_time(void)
-{
-       u64 system_time = 0;
-       struct timeval tv;
-       do_gettimeofday(&tv);
-
-       /* We are interested in seconds only. */
-       system_time = tv.tv_sec;
-       return system_time;
-}
-
-#define bfa_io_lat_clock_res_div HZ
-#define bfa_io_lat_clock_res_mul 1000
-
-#define BFA_LOG(level, bfad, mask, fmt, arg...)                                \
-do {                                                                   \
-       if (((mask) == 4) || (level[1] <= '4'))                         \
-               dev_printk(level, &((bfad)->pcidev)->dev, fmt, ##arg);  \
-} while (0)
-
-#define bfa_swap_3b(_x)                                \
-       ((((_x) & 0xff) << 16) |                \
-       ((_x) & 0x00ff00) |                     \
-       (((_x) & 0xff0000) >> 16))
-
-#define bfa_os_swap_sgaddr(_x)  ((u64)(                                 \
-       (((u64)(_x) & (u64)0x00000000000000ffull) << 32)        |       \
-       (((u64)(_x) & (u64)0x000000000000ff00ull) << 32)        |       \
-       (((u64)(_x) & (u64)0x0000000000ff0000ull) << 32)        |       \
-       (((u64)(_x) & (u64)0x00000000ff000000ull) << 32)        |       \
-       (((u64)(_x) & (u64)0x000000ff00000000ull) >> 32)        |       \
-       (((u64)(_x) & (u64)0x0000ff0000000000ull) >> 32)        |       \
-       (((u64)(_x) & (u64)0x00ff000000000000ull) >> 32)        |       \
-       (((u64)(_x) & (u64)0xff00000000000000ull) >> 32)))
-
-#ifndef __BIGENDIAN
-#define bfa_os_hton3b(_x)  bfa_swap_3b(_x)
-#define bfa_os_sgaddr(_x)  (_x)
-#else
-#define bfa_os_hton3b(_x)  (_x)
-#define bfa_os_sgaddr(_x)  bfa_os_swap_sgaddr(_x)
-#endif
-
-#define bfa_os_ntoh3b(_x)  bfa_os_hton3b(_x)
-#define bfa_os_u32(__pa64) ((__pa64) >> 32)
-
-#define BFA_TRC_TS(_trcm)                              \
-       ({                                              \
-               struct timeval tv;                      \
-                                                       \
-               do_gettimeofday(&tv);                   \
-               (tv.tv_sec*1000000+tv.tv_usec);         \
-        })
-
-#define boolean_t int
-
-/*
- * For current time stamp, OS API will fill-in
- */
-struct bfa_timeval_s {
-       u32     tv_sec;         /*  seconds        */
-       u32     tv_usec;        /*  microseconds   */
-};
-
-static inline void
-bfa_os_gettimeofday(struct bfa_timeval_s *tv)
-{
-       struct timeval  tmp_tv;
-
-       do_gettimeofday(&tmp_tv);
-       tv->tv_sec = (u32) tmp_tv.tv_sec;
-       tv->tv_usec = (u32) tmp_tv.tv_usec;
-}
-
-static inline void
-wwn2str(char *wwn_str, u64 wwn)
-{
-       union {
-               u64 wwn;
-               u8 byte[8];
-       } w;
-
-       w.wwn = wwn;
-       sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", w.byte[0],
-               w.byte[1], w.byte[2], w.byte[3], w.byte[4], w.byte[5],
-               w.byte[6], w.byte[7]);
-}
-
-static inline void
-fcid2str(char *fcid_str, u32 fcid)
-{
-       union {
-               u32 fcid;
-               u8 byte[4];
-       } f;
-
-       f.fcid = fcid;
-       sprintf(fcid_str, "%02x:%02x:%02x", f.byte[1], f.byte[2], f.byte[3]);
-}
-
-#endif /* __BFA_OS_INC_H__ */
index 501f0ed35cf08ad7e063a79d3d1c0f7618ce452f..1c9baa68339b4bee83f53d64e439c0dddd1b2812 100644 (file)
@@ -151,9 +151,5 @@ void bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
 void bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
                        enum bfa_plog_eid event, u16 misc,
                        struct fchs_s *fchdr, u32 pld_w0);
-void bfa_plog_clear(struct bfa_plog_s *plog);
-void bfa_plog_enable(struct bfa_plog_s *plog);
-void bfa_plog_disable(struct bfa_plog_s *plog);
-bfa_boolean_t  bfa_plog_get_setting(struct bfa_plog_s *plog);
 
 #endif /* __BFA_PORTLOG_H__ */
index fff96226a383c6c06363d9e1036301f88d5bf8ac..45b3486cca9ce0c003c8c707ba11c47b875968e5 100644 (file)
@@ -15,6 +15,7 @@
  * General Public License for more details.
  */
 
+#include "bfad_drv.h"
 #include "bfa_defs_svc.h"
 #include "bfa_port.h"
 #include "bfi.h"
@@ -29,14 +30,14 @@ static void
 bfa_port_stats_swap(struct bfa_port_s *port, union bfa_port_stats_u *stats)
 {
        u32    *dip = (u32 *) stats;
-       u32    t0, t1;
+       __be32    t0, t1;
        int         i;
 
        for (i = 0; i < sizeof(union bfa_port_stats_u)/sizeof(u32);
                i += 2) {
                t0 = dip[i];
                t1 = dip[i + 1];
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
                dip[i] = be32_to_cpu(t0);
                dip[i + 1] = be32_to_cpu(t1);
 #else
@@ -96,13 +97,13 @@ bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
        port->stats_busy = BFA_FALSE;
 
        if (status == BFA_STATUS_OK) {
-               struct bfa_timeval_s tv;
+               struct timeval tv;
 
                memcpy(port->stats, port->stats_dma.kva,
                       sizeof(union bfa_port_stats_u));
                bfa_port_stats_swap(port, port->stats);
 
-               bfa_os_gettimeofday(&tv);
+               do_gettimeofday(&tv);
                port->stats->fc.secs_reset = tv.tv_sec - port->stats_reset_time;
        }
 
@@ -124,7 +125,7 @@ bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
 static void
 bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
 {
-       struct bfa_timeval_s tv;
+       struct timeval tv;
 
        port->stats_status = status;
        port->stats_busy   = BFA_FALSE;
@@ -132,7 +133,7 @@ bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
        /*
        * re-initialize time stamp for stats reset
        */
-       bfa_os_gettimeofday(&tv);
+       do_gettimeofday(&tv);
        port->stats_reset_time = tv.tv_sec;
 
        if (port->stats_cbfn) {
@@ -432,7 +433,7 @@ void
 bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
                 void *dev, struct bfa_trc_mod_s *trcmod)
 {
-       struct bfa_timeval_s tv;
+       struct timeval tv;
 
        bfa_assert(port);
 
@@ -447,27 +448,13 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
 
        bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
        bfa_ioc_hbfail_init(&port->hbfail, bfa_port_hbfail, port);
-       bfa_ioc_hbfail_register(port->ioc, &port->hbfail);
+       list_add_tail(&port->hbfail.qe, &port->ioc->hb_notify_q);
 
        /*
         * initialize time stamp for stats reset
         */
-       bfa_os_gettimeofday(&tv);
+       do_gettimeofday(&tv);
        port->stats_reset_time = tv.tv_sec;
 
        bfa_trc(port, 0);
 }
-
-/*
- * bfa_port_detach()
- *
- *
- * @param[in] port - Pointer to the Port module data structure
- *
- * @return void
- */
-void
-bfa_port_detach(struct bfa_port_s *port)
-{
-       bfa_trc(port, 0);
-}
index dbce9dfd056b21982d087c84d8d0f7dbe779d9af..c4ee9db6b4701f06ea7f825bc1413702aa55f357 100644 (file)
@@ -48,7 +48,6 @@ struct bfa_port_s {
 
 void        bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
                                void *dev, struct bfa_trc_mod_s *trcmod);
-void        bfa_port_detach(struct bfa_port_s *port);
 void        bfa_port_hbfail(void *arg);
 
 bfa_status_t bfa_port_get_stats(struct bfa_port_s *port,
index c768143f4805a7cb5f0094682a39c30b73ea433d..b7df5534da857834edf300d282399603fcf24f89 100644 (file)
  * General Public License for more details.
  */
 
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 #include "bfa_plog.h"
 #include "bfa_cs.h"
 #include "bfa_modules.h"
-#include "bfad_drv.h"
 
 BFA_TRC_FILE(HAL, FCXP);
 BFA_MODULE(fcxp);
@@ -41,19 +40,6 @@ BFA_MODULE(uf);
 #define BFA_LPS_MAX_VPORTS_SUPP_CB  255
 #define BFA_LPS_MAX_VPORTS_SUPP_CT  190
 
-/*
- *  lps_pvt BFA LPS private functions
- */
-
-enum bfa_lps_event {
-       BFA_LPS_SM_LOGIN        = 1,    /* login request from user      */
-       BFA_LPS_SM_LOGOUT       = 2,    /* logout request from user     */
-       BFA_LPS_SM_FWRSP        = 3,    /* f/w response to login/logout */
-       BFA_LPS_SM_RESUME       = 4,    /* space present in reqq queue  */
-       BFA_LPS_SM_DELETE       = 5,    /* lps delete from user         */
-       BFA_LPS_SM_OFFLINE      = 6,    /* Link is offline              */
-       BFA_LPS_SM_RX_CVL       = 7,    /* Rx clear virtual link        */
-};
 
 /*
  * FC PORT related definitions
@@ -66,7 +52,6 @@ enum bfa_lps_event {
        ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
        (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
 
-
 /*
  * BFA port state machine events
  */
@@ -113,19 +98,6 @@ enum bfa_fcport_ln_sm_event {
                }                                                       \
 } while (0)
 
-
-enum bfa_rport_event {
-       BFA_RPORT_SM_CREATE     = 1,    /*  rport create event          */
-       BFA_RPORT_SM_DELETE     = 2,    /*  deleting an existing rport  */
-       BFA_RPORT_SM_ONLINE     = 3,    /*  rport is online             */
-       BFA_RPORT_SM_OFFLINE    = 4,    /*  rport is offline            */
-       BFA_RPORT_SM_FWRSP      = 5,    /*  firmware response           */
-       BFA_RPORT_SM_HWFAIL     = 6,    /*  IOC h/w failure             */
-       BFA_RPORT_SM_QOS_SCN    = 7,    /*  QoS SCN from firmware       */
-       BFA_RPORT_SM_SET_SPEED  = 8,    /*  Set Rport Speed             */
-       BFA_RPORT_SM_QRESUME    = 9,    /*  space in requeue queue      */
-};
-
 /*
  * forward declarations FCXP related functions
  */
@@ -159,6 +131,7 @@ static void bfa_lps_reqq_resume(void *lps_arg);
 static void bfa_lps_free(struct bfa_lps_s *lps);
 static void bfa_lps_send_login(struct bfa_lps_s *lps);
 static void bfa_lps_send_logout(struct bfa_lps_s *lps);
+static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps);
 static void bfa_lps_login_comp(struct bfa_lps_s *lps);
 static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
 static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
@@ -171,6 +144,8 @@ static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event);
 static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event
                                        event);
 static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event);
+static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps,
+                                       enum bfa_lps_event event);
 static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
 static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event
                                        event);
@@ -312,6 +287,18 @@ plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec)
        return 0;
 }
 
+static u64
+bfa_get_log_time(void)
+{
+       u64 system_time = 0;
+       struct timeval tv;
+       do_gettimeofday(&tv);
+
+       /* We are interested in seconds only. */
+       system_time = tv.tv_sec;
+       return system_time;
+}
+
 static void
 bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
 {
@@ -332,7 +319,7 @@ bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
 
        memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
 
-       pl_recp->tv = bfa_os_get_log_time();
+       pl_recp->tv = bfa_get_log_time();
        BFA_PL_LOG_REC_INCR(plog->tail);
 
        if (plog->head == plog->tail)
@@ -437,29 +424,6 @@ bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
        }
 }
 
-void
-bfa_plog_clear(struct bfa_plog_s *plog)
-{
-       plog->head = plog->tail = 0;
-}
-
-void
-bfa_plog_enable(struct bfa_plog_s *plog)
-{
-       plog->plog_enabled = 1;
-}
-
-void
-bfa_plog_disable(struct bfa_plog_s *plog)
-{
-       plog->plog_enabled = 0;
-}
-
-bfa_boolean_t
-bfa_plog_get_setting(struct bfa_plog_s *plog)
-{
-       return (bfa_boolean_t)plog->plog_enabled;
-}
 
 /*
  *  fcxp_pvt BFA FCXP private functions
@@ -954,10 +918,6 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
        bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
 }
 
-/*
- *  hal_fcxp_api BFA FCXP API
- */
-
 /*
  * Allocate an FCXP instance to send a response or to send a request
  * that has a response. Request/response buffers are allocated by caller.
@@ -1052,7 +1012,7 @@ bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
 }
 
 /*
- *             Free the BFA FCXP
+ * Free the BFA FCXP
  *
  * @param[in]  fcxp                    BFA fcxp pointer
  *
@@ -1199,12 +1159,6 @@ bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
        fcxp->send_cbfn = bfa_fcxp_null_comp;
 }
 
-
-
-/*
- *  hal_fcxp_public BFA FCXP public functions
- */
-
 void
 bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 {
@@ -1303,6 +1257,12 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
                        else
                                bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
                                        BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
+                       /* If N2N, send the assigned PID to FW */
+                       bfa_trc(lps->bfa, lps->fport);
+                       bfa_trc(lps->bfa, lps->lp_pid);
+
+                       if (!lps->fport && lps->lp_pid)
+                               bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
                } else {
                        bfa_sm_set_state(lps, bfa_lps_sm_init);
                        if (lps->fdisc)
@@ -1321,6 +1281,11 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
                bfa_sm_set_state(lps, bfa_lps_sm_init);
                break;
 
+       case BFA_LPS_SM_SET_N2N_PID:
+               bfa_trc(lps->bfa, lps->fport);
+               bfa_trc(lps->bfa, lps->lp_pid);
+               break;
+
        default:
                bfa_sm_fault(lps->bfa, event);
        }
@@ -1389,9 +1354,59 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
                        BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
                break;
 
+       case BFA_LPS_SM_SET_N2N_PID:
+               if (bfa_reqq_full(lps->bfa, lps->reqq)) {
+                       bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait);
+                       bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
+               } else
+                       bfa_lps_send_set_n2n_pid(lps);
+               break;
+
+       case BFA_LPS_SM_OFFLINE:
+       case BFA_LPS_SM_DELETE:
+               bfa_sm_set_state(lps, bfa_lps_sm_init);
+               break;
+
+       default:
+               bfa_sm_fault(lps->bfa, event);
+       }
+}
+
+/**
+ * login complete
+ */
+static void
+bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event)
+{
+       bfa_trc(lps->bfa, lps->lp_tag);
+       bfa_trc(lps->bfa, event);
+
+       switch (event) {
+       case BFA_LPS_SM_RESUME:
+               bfa_sm_set_state(lps, bfa_lps_sm_online);
+               bfa_lps_send_set_n2n_pid(lps);
+               break;
+
+       case BFA_LPS_SM_LOGOUT:
+               bfa_sm_set_state(lps, bfa_lps_sm_logowait);
+               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_LOGO, 0, "Logout");
+               break;
+
+       case BFA_LPS_SM_RX_CVL:
+               bfa_sm_set_state(lps, bfa_lps_sm_init);
+               bfa_reqq_wcancel(&lps->wqe);
+
+               /* Let the vport module know about this event */
+               bfa_lps_cvl_event(lps);
+               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
+               break;
+
        case BFA_LPS_SM_OFFLINE:
        case BFA_LPS_SM_DELETE:
                bfa_sm_set_state(lps, bfa_lps_sm_init);
+               bfa_reqq_wcancel(&lps->wqe);
                break;
 
        default:
@@ -1547,8 +1562,9 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
        switch (rsp->status) {
        case BFA_STATUS_OK:
                lps->fport      = rsp->f_port;
+               if (lps->fport)
+                       lps->lp_pid = rsp->lp_pid;
                lps->npiv_en    = rsp->npiv_en;
-               lps->lp_pid     = rsp->lp_pid;
                lps->pr_bbcred  = be16_to_cpu(rsp->bb_credit);
                lps->pr_pwwn    = rsp->port_name;
                lps->pr_nwwn    = rsp->node_name;
@@ -1675,6 +1691,25 @@ bfa_lps_send_logout(struct bfa_lps_s *lps)
        bfa_reqq_produce(lps->bfa, lps->reqq);
 }
 
+/**
+ * send n2n pid set request to firmware
+ */
+static void
+bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps)
+{
+       struct bfi_lps_n2n_pid_req_s *m;
+
+       m = bfa_reqq_next(lps->bfa, lps->reqq);
+       bfa_assert(m);
+
+       bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ,
+               bfa_lpuid(lps->bfa));
+
+       m->lp_tag = lps->lp_tag;
+       m->lp_pid = lps->lp_pid;
+       bfa_reqq_produce(lps->bfa, lps->reqq);
+}
+
 /*
  * Indirect login completion handler for non-fcs
  */
@@ -1853,14 +1888,6 @@ bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
        bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
 }
 
-/*
- * Initiate a lport logout (flogi).
- */
-void
-bfa_lps_flogo(struct bfa_lps_s *lps)
-{
-       bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
-}
 
 /*
  * Initiate a lport FDSIC logout.
@@ -1871,24 +1898,6 @@ bfa_lps_fdisclogo(struct bfa_lps_s *lps)
        bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
 }
 
-/*
- * Discard a pending login request -- should be called only for
- * link down handling.
- */
-void
-bfa_lps_discard(struct bfa_lps_s *lps)
-{
-       bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
-}
-
-/*
- * Return lport services tag
- */
-u8
-bfa_lps_get_tag(struct bfa_lps_s *lps)
-{
-       return lps->lp_tag;
-}
 
 /*
  * Return lport services tag given the pid
@@ -1909,55 +1918,6 @@ bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid)
        return 0;
 }
 
-/*
- * return if fabric login indicates support for NPIV
- */
-bfa_boolean_t
-bfa_lps_is_npiv_en(struct bfa_lps_s *lps)
-{
-       return lps->npiv_en;
-}
-
-/*
- * Return TRUE if attached to F-Port, else return FALSE
- */
-bfa_boolean_t
-bfa_lps_is_fport(struct bfa_lps_s *lps)
-{
-       return lps->fport;
-}
-
-/*
- * Return TRUE if attached to a Brocade Fabric
- */
-bfa_boolean_t
-bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps)
-{
-       return lps->brcd_switch;
-}
-/*
- * return TRUE if authentication is required
- */
-bfa_boolean_t
-bfa_lps_is_authreq(struct bfa_lps_s *lps)
-{
-       return lps->auth_req;
-}
-
-bfa_eproto_status_t
-bfa_lps_get_extstatus(struct bfa_lps_s *lps)
-{
-       return lps->ext_status;
-}
-
-/*
- * return port id assigned to the lport
- */
-u32
-bfa_lps_get_pid(struct bfa_lps_s *lps)
-{
-       return lps->lp_pid;
-}
 
 /*
  * return port id assigned to the base lport
@@ -1970,58 +1930,17 @@ bfa_lps_get_base_pid(struct bfa_s *bfa)
        return BFA_LPS_FROM_TAG(mod, 0)->lp_pid;
 }
 
-/*
- * Return bb_credit assigned in FLOGI response
- */
-u16
-bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps)
-{
-       return lps->pr_bbcred;
-}
-
-/*
- * Return peer port name
- */
-wwn_t
-bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps)
-{
-       return lps->pr_pwwn;
-}
-
-/*
- * Return peer node name
- */
-wwn_t
-bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps)
-{
-       return lps->pr_nwwn;
-}
-
-/*
- * return reason code if login request is rejected
- */
-u8
-bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps)
-{
-       return lps->lsrjt_rsn;
-}
-
-/*
- * return explanation code if login request is rejected
+/**
+ * Set PID in case of n2n (which is assigned during PLOGI)
  */
-u8
-bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
+void
+bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid)
 {
-       return lps->lsrjt_expl;
-}
+       bfa_trc(lps->bfa, lps->lp_tag);
+       bfa_trc(lps->bfa, n2n_pid);
 
-/*
- * Return fpma/spma MAC for lport
- */
-mac_t
-bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
-{
-       return lps->lp_mac;
+       lps->lp_pid = n2n_pid;
+       bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
 }
 
 /*
@@ -2068,6 +1987,8 @@ bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
                /*
                 * Start event after IOC is configured and BFA is started.
                 */
+               fcport->use_flash_cfg = BFA_TRUE;
+
                if (bfa_fcport_send_enable(fcport)) {
                        bfa_trc(fcport->bfa, BFA_TRUE);
                        bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
@@ -2138,7 +2059,7 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port disabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2198,7 +2119,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port disabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2251,7 +2172,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
 
                bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE);
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port online: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2277,7 +2198,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port disabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2322,9 +2243,9 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port offline: WWN = %s\n", pwwn_buf);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port disabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2336,10 +2257,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
                                BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
                wwn2str(pwwn_buf, fcport->pwwn);
                if (BFA_PORT_IS_DISABLED(fcport->bfa))
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "Base port offline: WWN = %s\n", pwwn_buf);
                else
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "Base port (WWN = %s) "
                                "lost fabric connectivity\n", pwwn_buf);
                break;
@@ -2349,10 +2270,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
                bfa_fcport_reset_linkinfo(fcport);
                wwn2str(pwwn_buf, fcport->pwwn);
                if (BFA_PORT_IS_DISABLED(fcport->bfa))
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "Base port offline: WWN = %s\n", pwwn_buf);
                else
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "Base port (WWN = %s) "
                                "lost fabric connectivity\n", pwwn_buf);
                break;
@@ -2363,10 +2284,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
                bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
                wwn2str(pwwn_buf, fcport->pwwn);
                if (BFA_PORT_IS_DISABLED(fcport->bfa))
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "Base port offline: WWN = %s\n", pwwn_buf);
                else
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "Base port (WWN = %s) "
                                "lost fabric connectivity\n", pwwn_buf);
                break;
@@ -2497,7 +2418,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port enabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2551,7 +2472,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port enabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2803,12 +2724,6 @@ bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
        }
 }
 
-
-
-/*
- *  hal_port_private
- */
-
 static void
 __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
 {
@@ -2906,7 +2821,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
        struct bfa_port_cfg_s *port_cfg = &fcport->cfg;
        struct bfa_fcport_ln_s *ln = &fcport->ln;
-       struct bfa_timeval_s tv;
+       struct timeval tv;
 
        memset(fcport, 0, sizeof(struct bfa_fcport_s));
        fcport->bfa = bfa;
@@ -2920,7 +2835,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        /*
         * initialize time stamp for stats reset
         */
-       bfa_os_gettimeofday(&tv);
+       do_gettimeofday(&tv);
        fcport->stats_reset_time = tv.tv_sec;
 
        /*
@@ -3039,6 +2954,7 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
        m->port_cfg = fcport->cfg;
        m->msgtag = fcport->msgtag;
        m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize);
+        m->use_flash_cfg = fcport->use_flash_cfg;
        bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
        bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
        bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
@@ -3089,8 +3005,8 @@ bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
 static void
 bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
 {
-       fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
-       fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
+       fcport->pwwn = fcport->bfa->ioc.attr->pwwn;
+       fcport->nwwn = fcport->bfa->ioc.attr->nwwn;
 
        bfa_trc(fcport->bfa, fcport->pwwn);
        bfa_trc(fcport->bfa, fcport->nwwn);
@@ -3127,7 +3043,7 @@ bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
        struct bfa_qos_stats_s *s)
 {
        u32     *dip = (u32 *) d;
-       u32     *sip = (u32 *) s;
+       __be32  *sip = (__be32 *) s;
        int             i;
 
        /* Now swap the 32 bit fields */
@@ -3140,12 +3056,12 @@ bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
        struct bfa_fcoe_stats_s *s)
 {
        u32     *dip = (u32 *) d;
-       u32     *sip = (u32 *) s;
+       __be32  *sip = (__be32 *) s;
        int             i;
 
        for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
             i = i + 2) {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
                dip[i] = be32_to_cpu(sip[i]);
                dip[i + 1] = be32_to_cpu(sip[i + 1]);
 #else
@@ -3162,7 +3078,7 @@ __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
 
        if (complete) {
                if (fcport->stats_status == BFA_STATUS_OK) {
-                       struct bfa_timeval_s tv;
+                       struct timeval tv;
 
                        /* Swap FC QoS or FCoE stats */
                        if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
@@ -3174,7 +3090,7 @@ __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
                                        &fcport->stats_ret->fcoe,
                                        &fcport->stats->fcoe);
 
-                               bfa_os_gettimeofday(&tv);
+                               do_gettimeofday(&tv);
                                fcport->stats_ret->fcoe.secs_reset =
                                        tv.tv_sec - fcport->stats_reset_time;
                        }
@@ -3233,12 +3149,12 @@ __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
        struct bfa_fcport_s *fcport = cbarg;
 
        if (complete) {
-               struct bfa_timeval_s tv;
+               struct timeval tv;
 
                /*
                 * re-initialize time stamp for stats reset
                 */
-               bfa_os_gettimeofday(&tv);
+               do_gettimeofday(&tv);
                fcport->stats_reset_time = tv.tv_sec;
 
                fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
@@ -3396,12 +3312,6 @@ bfa_trunk_iocdisable(struct bfa_s *bfa)
        }
 }
 
-
-
-/*
- *  hal_port_public
- */
-
 /*
  * Called to initialize port attributes
  */
@@ -3441,8 +3351,28 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 
        switch (msg->mhdr.msg_id) {
        case BFI_FCPORT_I2H_ENABLE_RSP:
-               if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+               if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) {
+
+                       if (fcport->use_flash_cfg) {
+                               fcport->cfg = i2hmsg.penable_rsp->port_cfg;
+                               fcport->cfg.maxfrsize =
+                                       cpu_to_be16(fcport->cfg.maxfrsize);
+                               fcport->cfg.path_tov =
+                                       cpu_to_be16(fcport->cfg.path_tov);
+                               fcport->cfg.q_depth =
+                                       cpu_to_be16(fcport->cfg.q_depth);
+
+                               if (fcport->cfg.trunked)
+                                       fcport->trunk.attr.state =
+                                               BFA_TRUNK_OFFLINE;
+                               else
+                                       fcport->trunk.attr.state =
+                                               BFA_TRUNK_DISABLED;
+                               fcport->use_flash_cfg = BFA_FALSE;
+                       }
+
                        bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
+               }
                break;
 
        case BFI_FCPORT_I2H_DISABLE_RSP:
@@ -3503,12 +3433,6 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
        }
 }
 
-
-
-/*
- *  hal_port_api
- */
-
 /*
  * Registered callback for port events.
  */
@@ -3732,8 +3656,8 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
        attr->nwwn = fcport->nwwn;
        attr->pwwn = fcport->pwwn;
 
-       attr->factorypwwn =  bfa_ioc_get_mfg_pwwn(&bfa->ioc);
-       attr->factorynwwn =  bfa_ioc_get_mfg_nwwn(&bfa->ioc);
+       attr->factorypwwn =  bfa->ioc.attr->mfg_pwwn;
+       attr->factorynwwn =  bfa->ioc.attr->mfg_nwwn;
 
        memcpy(&attr->pport_cfg, &fcport->cfg,
                sizeof(struct bfa_port_cfg_s));
@@ -3751,7 +3675,7 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
        /* beacon attributes */
        attr->beacon = fcport->beacon;
        attr->link_e2e_beacon = fcport->link_e2e_beacon;
-       attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
+       attr->plog_enabled = (bfa_boolean_t)fcport->bfa->plog->plog_enabled;
        attr->io_profile = bfa_fcpim_get_io_profile(fcport->bfa);
 
        attr->pport_cfg.path_tov  = bfa_fcpim_path_tov_get(bfa);
@@ -3818,89 +3742,6 @@ bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
        return BFA_STATUS_OK;
 }
 
-/*
- * Fetch FCQoS port statistics
- */
-bfa_status_t
-bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
-       bfa_cb_port_t cbfn, void *cbarg)
-{
-       /* Meaningful only for FC mode */
-       bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
-
-       return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
-}
-
-/*
- * Reset FCoE port statistics
- */
-bfa_status_t
-bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
-{
-       /* Meaningful only for FC mode */
-       bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
-
-       return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
-}
-
-/*
- * Fetch FCQoS port statistics
- */
-bfa_status_t
-bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
-       bfa_cb_port_t cbfn, void *cbarg)
-{
-       /* Meaningful only for FCoE mode */
-       bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
-
-       return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
-}
-
-/*
- * Reset FCoE port statistics
- */
-bfa_status_t
-bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
-{
-       /* Meaningful only for FCoE mode */
-       bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
-
-       return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
-}
-
-void
-bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
-       qos_attr->state = fcport->qos_attr.state;
-       qos_attr->total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr);
-}
-
-void
-bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
-       struct bfa_qos_vc_attr_s *qos_vc_attr)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-       struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
-       u32 i = 0;
-
-       qos_vc_attr->total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count);
-       qos_vc_attr->shared_credit  = be16_to_cpu(bfa_vc_attr->shared_credit);
-       qos_vc_attr->elp_opmode_flags  =
-                       be32_to_cpu(bfa_vc_attr->elp_opmode_flags);
-
-       /* Individual VC info */
-       while (i < qos_vc_attr->total_vc_count) {
-               qos_vc_attr->vc_info[i].vc_credit       =
-                               bfa_vc_attr->vc_info[i].vc_credit;
-               qos_vc_attr->vc_info[i].borrow_credit   =
-                               bfa_vc_attr->vc_info[i].borrow_credit;
-               qos_vc_attr->vc_info[i].priority        =
-                               bfa_vc_attr->vc_info[i].priority;
-               ++i;
-       }
-}
 
 /*
  * Fetch port attributes.
@@ -3924,60 +3765,6 @@ bfa_fcport_is_ratelim(struct bfa_s *bfa)
 
 }
 
-void
-bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-       enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
-
-       bfa_trc(bfa, on_off);
-       bfa_trc(bfa, fcport->cfg.qos_enabled);
-
-       bfa_trc(bfa, ioc_type);
-
-       if (ioc_type == BFA_IOC_TYPE_FC) {
-               fcport->cfg.qos_enabled = on_off;
-               /*
-                * Notify fcpim of the change in QoS state
-                */
-               bfa_fcpim_update_ioredirect(bfa);
-       }
-}
-
-void
-bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
-       bfa_trc(bfa, on_off);
-       bfa_trc(bfa, fcport->cfg.ratelimit);
-
-       fcport->cfg.ratelimit = on_off;
-       if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN)
-               fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
-}
-
-/*
- * Configure default minimum ratelim speed
- */
-bfa_status_t
-bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
-       bfa_trc(bfa, speed);
-
-       /* Auto and speeds greater than the supported speed, are invalid */
-       if ((speed == BFA_PORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
-               bfa_trc(bfa, fcport->speed_sup);
-               return BFA_STATUS_UNSUPP_SPEED;
-       }
-
-       fcport->cfg.trl_def_speed = speed;
-
-       return BFA_STATUS_OK;
-}
-
 /*
  * Get default minimum ratelim speed
  */
@@ -3990,32 +3777,6 @@ bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
        return fcport->cfg.trl_def_speed;
 
 }
-void
-bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
-       bfa_trc(bfa, status);
-       bfa_trc(bfa, fcport->diag_busy);
-
-       fcport->diag_busy = status;
-}
-
-void
-bfa_fcport_beacon(void *dev, bfa_boolean_t beacon,
-       bfa_boolean_t link_e2e_beacon)
-{
-       struct bfa_s *bfa = dev;
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
-       bfa_trc(bfa, beacon);
-       bfa_trc(bfa, link_e2e_beacon);
-       bfa_trc(bfa, fcport->beacon);
-       bfa_trc(bfa, fcport->link_e2e_beacon);
-
-       fcport->beacon = beacon;
-       fcport->link_e2e_beacon = link_e2e_beacon;
-}
 
 bfa_boolean_t
 bfa_fcport_is_linkup(struct bfa_s *bfa)
@@ -4036,63 +3797,6 @@ bfa_fcport_is_qos_enabled(struct bfa_s *bfa)
        return fcport->cfg.qos_enabled;
 }
 
-bfa_status_t
-bfa_trunk_get_attr(struct bfa_s *bfa, struct bfa_trunk_attr_s *attr)
-
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-       struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
-
-       bfa_trc(bfa, fcport->cfg.trunked);
-       bfa_trc(bfa, trunk->attr.state);
-       *attr = trunk->attr;
-       attr->port_id = bfa_lps_get_base_pid(bfa);
-
-       return BFA_STATUS_OK;
-}
-
-void
-bfa_trunk_enable_cfg(struct bfa_s *bfa)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-       struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
-
-       bfa_trc(bfa, 1);
-       trunk->attr.state = BFA_TRUNK_OFFLINE;
-       fcport->cfg.trunked = BFA_TRUE;
-}
-
-bfa_status_t
-bfa_trunk_enable(struct bfa_s *bfa)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-       struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
-
-       bfa_trc(bfa, 1);
-
-       trunk->attr.state   = BFA_TRUNK_OFFLINE;
-       bfa_fcport_disable(bfa);
-       fcport->cfg.trunked = BFA_TRUE;
-       bfa_fcport_enable(bfa);
-
-       return BFA_STATUS_OK;
-}
-
-bfa_status_t
-bfa_trunk_disable(struct bfa_s *bfa)
-{
-       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-       struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
-
-       bfa_trc(bfa, 0);
-       trunk->attr.state   = BFA_TRUNK_DISABLED;
-       bfa_fcport_disable(bfa);
-       fcport->cfg.trunked = BFA_FALSE;
-       bfa_fcport_enable(bfa);
-       return BFA_STATUS_OK;
-}
-
-
 /*
  * Rport State machine functions
  */
@@ -4828,7 +4532,7 @@ bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
 
        rp->bfa = bfa;
        rp->rport_drv = rport_drv;
-       bfa_rport_clear_stats(rp);
+       memset(&rp->stats, 0, sizeof(rp->stats));
 
        bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
        bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
@@ -4836,12 +4540,6 @@ bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
        return rp;
 }
 
-void
-bfa_rport_delete(struct bfa_rport_s *rport)
-{
-       bfa_sm_send_event(rport, BFA_RPORT_SM_DELETE);
-}
-
 void
 bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
 {
@@ -4860,12 +4558,6 @@ bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
        bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE);
 }
 
-void
-bfa_rport_offline(struct bfa_rport_s *rport)
-{
-       bfa_sm_send_event(rport, BFA_RPORT_SM_OFFLINE);
-}
-
 void
 bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
 {
@@ -4876,28 +4568,6 @@ bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
        bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
 }
 
-void
-bfa_rport_get_stats(struct bfa_rport_s *rport,
-       struct bfa_rport_hal_stats_s *stats)
-{
-       *stats = rport->stats;
-}
-
-void
-bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
-                                       struct bfa_rport_qos_attr_s *qos_attr)
-{
-       qos_attr->qos_priority  = rport->qos_attr.qos_priority;
-       qos_attr->qos_flow_id  = be32_to_cpu(rport->qos_attr.qos_flow_id);
-
-}
-
-void
-bfa_rport_clear_stats(struct bfa_rport_s *rport)
-{
-       memset(&rport->stats, 0, sizeof(rport->stats));
-}
-
 
 /*
  * SGPG related functions
@@ -4993,12 +4663,6 @@ bfa_sgpg_iocdisable(struct bfa_s *bfa)
 {
 }
 
-
-
-/*
- *  hal_sgpg_public BFA SGPG public functions
- */
-
 bfa_status_t
 bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs)
 {
@@ -5361,12 +5025,6 @@ bfa_uf_start(struct bfa_s *bfa)
        bfa_uf_post_all(BFA_UF_MOD(bfa));
 }
 
-
-
-/*
- *  hal_uf_api
- */
-
 /*
  * Register handler for all unsolicted recieve frames.
  *
index e2349d5cdb931124132e2c6a2b3cc52200dcf40b..331ad992a5812c53f02a4f0cf2d1e0911b2965da 100644 (file)
@@ -220,6 +220,18 @@ void       bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 /*
  * RPORT related defines
  */
+enum bfa_rport_event {
+       BFA_RPORT_SM_CREATE     = 1,    /*  rport create event          */
+       BFA_RPORT_SM_DELETE     = 2,    /*  deleting an existing rport  */
+       BFA_RPORT_SM_ONLINE     = 3,    /*  rport is online             */
+       BFA_RPORT_SM_OFFLINE    = 4,    /*  rport is offline            */
+       BFA_RPORT_SM_FWRSP      = 5,    /*  firmware response           */
+       BFA_RPORT_SM_HWFAIL     = 6,    /*  IOC h/w failure             */
+       BFA_RPORT_SM_QOS_SCN    = 7,    /*  QoS SCN from firmware       */
+       BFA_RPORT_SM_SET_SPEED  = 8,    /*  Set Rport Speed             */
+       BFA_RPORT_SM_QRESUME    = 9,    /*  space in requeue queue      */
+};
+
 #define BFA_RPORT_MIN  4
 
 struct bfa_rport_mod_s {
@@ -432,6 +444,7 @@ struct bfa_fcport_s {
        u8                      myalpa; /*  my ALPA in LOOP topology */
        u8                      rsvd[3];
        struct bfa_port_cfg_s   cfg;    /*  current port configuration */
+       bfa_boolean_t           use_flash_cfg; /* get port cfg from flash */
        struct bfa_qos_attr_s  qos_attr;   /* QoS Attributes */
        struct bfa_qos_vc_attr_s qos_vc_attr;  /*  VC info from ELP */
        struct bfa_reqq_wait_s  reqq_wait;
@@ -500,30 +513,9 @@ void bfa_fcport_event_register(struct bfa_s *bfa,
                        void (*event_cbfn) (void *cbarg,
                        enum bfa_port_linkstate event), void *event_cbarg);
 bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
-void bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
-void bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
-bfa_status_t bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa,
-                                         enum bfa_port_speed speed);
 enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
 
 void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
-void bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status);
-void bfa_fcport_beacon(void *dev, bfa_boolean_t beacon,
-                      bfa_boolean_t link_e2e_beacon);
-void bfa_fcport_qos_get_attr(struct bfa_s *bfa,
-                            struct bfa_qos_attr_s *qos_attr);
-void bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
-                               struct bfa_qos_vc_attr_s *qos_vc_attr);
-bfa_status_t bfa_fcport_get_qos_stats(struct bfa_s *bfa,
-                                     union bfa_fcport_stats_u *stats,
-                                     bfa_cb_port_t cbfn, void *cbarg);
-bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn,
-                                       void *cbarg);
-bfa_status_t bfa_fcport_get_fcoe_stats(struct bfa_s *bfa,
-                                      union bfa_fcport_stats_u *stats,
-                                      bfa_cb_port_t cbfn, void *cbarg);
-bfa_status_t bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn,
-                                        void *cbarg);
 bfa_boolean_t     bfa_fcport_is_ratelim(struct bfa_s *bfa);
 bfa_boolean_t  bfa_fcport_is_linkup(struct bfa_s *bfa);
 bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa,
@@ -537,14 +529,9 @@ bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa);
  * bfa rport API functions
  */
 struct bfa_rport_s *bfa_rport_create(struct bfa_s *bfa, void *rport_drv);
-void bfa_rport_delete(struct bfa_rport_s *rport);
 void bfa_rport_online(struct bfa_rport_s *rport,
                      struct bfa_rport_info_s *rport_info);
-void bfa_rport_offline(struct bfa_rport_s *rport);
 void bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed);
-void bfa_rport_get_stats(struct bfa_rport_s *rport,
-                        struct bfa_rport_hal_stats_s *stats);
-void bfa_rport_clear_stats(struct bfa_rport_s *rport);
 void bfa_cb_rport_online(void *rport);
 void bfa_cb_rport_offline(void *rport);
 void bfa_cb_rport_qos_scn_flowid(void *rport,
@@ -553,8 +540,6 @@ void bfa_cb_rport_qos_scn_flowid(void *rport,
 void bfa_cb_rport_qos_scn_prio(void *rport,
                               struct bfa_rport_qos_attr_s old_qos_attr,
                               struct bfa_rport_qos_attr_s new_qos_attr);
-void bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
-                           struct bfa_rport_qos_attr_s *qos_attr);
 
 /*
  * bfa fcxp API functions
@@ -619,38 +604,18 @@ void bfa_uf_free(struct bfa_uf_s *uf);
 u32 bfa_lps_get_max_vport(struct bfa_s *bfa);
 struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa);
 void bfa_lps_delete(struct bfa_lps_s *lps);
-void bfa_lps_discard(struct bfa_lps_s *lps);
 void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa,
                   u16 pdusz, wwn_t pwwn, wwn_t nwwn,
                   bfa_boolean_t auth_en);
 void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz,
                   wwn_t pwwn, wwn_t nwwn);
-void bfa_lps_flogo(struct bfa_lps_s *lps);
 void bfa_lps_fdisclogo(struct bfa_lps_s *lps);
-u8 bfa_lps_get_tag(struct bfa_lps_s *lps);
-bfa_boolean_t bfa_lps_is_npiv_en(struct bfa_lps_s *lps);
-bfa_boolean_t bfa_lps_is_fport(struct bfa_lps_s *lps);
-bfa_boolean_t bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps);
-bfa_boolean_t bfa_lps_is_authreq(struct bfa_lps_s *lps);
-bfa_eproto_status_t bfa_lps_get_extstatus(struct bfa_lps_s *lps);
-u32 bfa_lps_get_pid(struct bfa_lps_s *lps);
+void bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, u32 n2n_pid);
 u32 bfa_lps_get_base_pid(struct bfa_s *bfa);
 u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid);
-u16 bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps);
-wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps);
-wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps);
-u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps);
-u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps);
-mac_t bfa_lps_get_lp_mac(struct bfa_lps_s *lps);
 void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
 void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
 void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
 void bfa_cb_lps_cvl_event(void *bfad, void *uarg);
 
-void bfa_trunk_enable_cfg(struct bfa_s *bfa);
-bfa_status_t bfa_trunk_enable(struct bfa_s *bfa);
-bfa_status_t bfa_trunk_disable(struct bfa_s *bfa);
-bfa_status_t bfa_trunk_get_attr(struct bfa_s *bfa,
-               struct bfa_trunk_attr_s *attr);
-
 #endif /* __BFA_SVC_H__ */
index 1f938974b84876978600b40d97c265ddd7c2c7c0..c80540e576cd6cccfe7d0bc507bec91efa52f3da 100644 (file)
@@ -32,7 +32,6 @@
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfa_fcs.h"
-#include "bfa_os_inc.h"
 #include "bfa_defs.h"
 #include "bfa.h"
 
@@ -50,7 +49,7 @@ int           reqq_size, rspq_size, num_sgpgs;
 int            rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
 int            bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
 int            bfa_io_max_sge = BFAD_IO_MAX_SGE;
-int            log_level = 3; /* WARNING log level */
+int            bfa_log_level = 3; /* WARNING log level */
 int            ioc_auto_recover = BFA_TRUE;
 int            bfa_linkup_delay = -1;
 int            fdmi_enable = BFA_TRUE;
@@ -61,12 +60,12 @@ int         msix_disable_cb = 0, msix_disable_ct = 0;
 u32    bfi_image_ct_fc_size, bfi_image_ct_cna_size, bfi_image_cb_fc_size;
 u32     *bfi_image_ct_fc, *bfi_image_ct_cna, *bfi_image_cb_fc;
 
-const char *msix_name_ct[] = {
+static const char *msix_name_ct[] = {
        "cpe0", "cpe1", "cpe2", "cpe3",
        "rme0", "rme1", "rme2", "rme3",
        "ctrl" };
 
-const char *msix_name_cb[] = {
+static const char *msix_name_cb[] = {
        "cpe0", "cpe1", "cpe2", "cpe3",
        "rme0", "rme1", "rme2", "rme3",
        "eemc", "elpu0", "elpu1", "epss", "mlpu" };
@@ -108,8 +107,8 @@ module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]");
 module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255");
-module_param(log_level, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(log_level, "Driver log level, default=3, "
+module_param(bfa_log_level, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(bfa_log_level, "Driver log level, default=3, "
                                "Range[Critical:1|Error:2|Warning:3|Info:4]");
 module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, "
@@ -206,7 +205,7 @@ bfad_sm_created(struct bfad_s *bfad, enum bfad_sm_event event)
                }
 
                spin_lock_irqsave(&bfad->bfad_lock, flags);
-               bfa_init(&bfad->bfa);
+               bfa_iocfc_init(&bfad->bfa);
                spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
                /* Set up interrupt handler for each vectors */
@@ -725,7 +724,7 @@ bfad_bfa_tmo(unsigned long data)
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
 
-       bfa_timer_tick(&bfad->bfa);
+       bfa_timer_beat(&bfad->bfa.timer_mod);
 
        bfa_comp_deq(&bfad->bfa, &doneq);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -882,8 +881,8 @@ bfad_drv_init(struct bfad_s *bfad)
                goto out_hal_mem_alloc_failure;
        }
 
-       bfa_init_trc(&bfad->bfa, bfad->trcmod);
-       bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
+       bfad->bfa.trcmod = bfad->trcmod;
+       bfad->bfa.plog = &bfad->plog_buf;
        bfa_plog_init(&bfad->plog_buf);
        bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
                     0, "Driver Attach");
@@ -893,9 +892,9 @@ bfad_drv_init(struct bfad_s *bfad)
 
        /* FCS INIT */
        spin_lock_irqsave(&bfad->bfad_lock, flags);
-       bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
+       bfad->bfa_fcs.trcmod = bfad->trcmod;
        bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
-       bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
+       bfad->bfa_fcs.fdmi_enabled = fdmi_enable;
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
        bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
@@ -913,7 +912,7 @@ bfad_drv_uninit(struct bfad_s *bfad)
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        init_completion(&bfad->comp);
-       bfa_stop(&bfad->bfa);
+       bfa_iocfc_stop(&bfad->bfa);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
        wait_for_completion(&bfad->comp);
 
@@ -932,8 +931,8 @@ bfad_drv_start(struct bfad_s *bfad)
        unsigned long   flags;
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
-       bfa_start(&bfad->bfa);
-       bfa_fcs_start(&bfad->bfa_fcs);
+       bfa_iocfc_start(&bfad->bfa);
+       bfa_fcs_fabric_modstart(&bfad->bfa_fcs);
        bfad->bfad_flags |= BFAD_HAL_START_DONE;
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
@@ -963,7 +962,7 @@ bfad_stop(struct bfad_s *bfad)
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        init_completion(&bfad->comp);
-       bfa_stop(&bfad->bfa);
+       bfa_iocfc_stop(&bfad->bfa);
        bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
        wait_for_completion(&bfad->comp);
@@ -1102,17 +1101,17 @@ bfad_start_ops(struct bfad_s *bfad) {
 
        /*
         * If bfa_linkup_delay is set to -1 default; try to retrive the
-        * value using the bfad_os_get_linkup_delay(); else use the
+        * value using the bfad_get_linkup_delay(); else use the
         * passed in module param value as the bfa_linkup_delay.
         */
        if (bfa_linkup_delay < 0) {
-               bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
-               bfad_os_rport_online_wait(bfad);
+               bfa_linkup_delay = bfad_get_linkup_delay(bfad);
+               bfad_rport_online_wait(bfad);
                bfa_linkup_delay = -1;
        } else
-               bfad_os_rport_online_wait(bfad);
+               bfad_rport_online_wait(bfad);
 
-       BFA_LOG(KERN_INFO, bfad, log_level, "bfa device claimed\n");
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level, "bfa device claimed\n");
 
        return BFA_STATUS_OK;
 }
@@ -1524,7 +1523,7 @@ bfad_init(void)
        if (strcmp(FCPI_NAME, " fcpim") == 0)
                supported_fc4s |= BFA_LPORT_ROLE_FCP_IM;
 
-       bfa_ioc_auto_recover(ioc_auto_recover);
+       bfa_auto_recover = ioc_auto_recover;
        bfa_fcs_rport_set_del_timeout(rport_del_timeout);
 
        error = pci_register_driver(&bfad_pci_driver);
index ed9fff440b5c3ef00014502120f7f475072b764e..a94ea4235433ad9bec99768ff3d25f2bb3aaefb0 100644 (file)
@@ -25,7 +25,7 @@
 /*
  * FC transport template entry, get SCSI target port ID.
  */
-void
+static void
 bfad_im_get_starget_port_id(struct scsi_target *starget)
 {
        struct Scsi_Host *shost;
@@ -40,7 +40,7 @@ bfad_im_get_starget_port_id(struct scsi_target *starget)
        bfad = im_port->bfad;
        spin_lock_irqsave(&bfad->bfad_lock, flags);
 
-       itnim = bfad_os_get_itnim(im_port, starget->id);
+       itnim = bfad_get_itnim(im_port, starget->id);
        if (itnim)
                fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
 
@@ -51,7 +51,7 @@ bfad_im_get_starget_port_id(struct scsi_target *starget)
 /*
  * FC transport template entry, get SCSI target nwwn.
  */
-void
+static void
 bfad_im_get_starget_node_name(struct scsi_target *starget)
 {
        struct Scsi_Host *shost;
@@ -66,7 +66,7 @@ bfad_im_get_starget_node_name(struct scsi_target *starget)
        bfad = im_port->bfad;
        spin_lock_irqsave(&bfad->bfad_lock, flags);
 
-       itnim = bfad_os_get_itnim(im_port, starget->id);
+       itnim = bfad_get_itnim(im_port, starget->id);
        if (itnim)
                node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim);
 
@@ -77,7 +77,7 @@ bfad_im_get_starget_node_name(struct scsi_target *starget)
 /*
  * FC transport template entry, get SCSI target pwwn.
  */
-void
+static void
 bfad_im_get_starget_port_name(struct scsi_target *starget)
 {
        struct Scsi_Host *shost;
@@ -92,7 +92,7 @@ bfad_im_get_starget_port_name(struct scsi_target *starget)
        bfad = im_port->bfad;
        spin_lock_irqsave(&bfad->bfad_lock, flags);
 
-       itnim = bfad_os_get_itnim(im_port, starget->id);
+       itnim = bfad_get_itnim(im_port, starget->id);
        if (itnim)
                port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
 
@@ -103,7 +103,7 @@ bfad_im_get_starget_port_name(struct scsi_target *starget)
 /*
  * FC transport template entry, get SCSI host port ID.
  */
-void
+static void
 bfad_im_get_host_port_id(struct Scsi_Host *shost)
 {
        struct bfad_im_port_s *im_port =
@@ -111,7 +111,7 @@ bfad_im_get_host_port_id(struct Scsi_Host *shost)
        struct bfad_port_s    *port = im_port->port;
 
        fc_host_port_id(shost) =
-                       bfa_os_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port));
+                       bfa_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port));
 }
 
 /*
@@ -487,7 +487,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
        wait_for_completion(vport->comp_del);
 
 free_scsi_host:
-       bfad_os_scsi_host_free(bfad, im_port);
+       bfad_scsi_host_free(bfad, im_port);
 
        kfree(vport);
 
index 1fedeeb4ac1f87dd69e4945c6c3b65fdd4cdab37..c66e32eced7b5ca119ea30c0fc9b83af969cf347 100644 (file)
@@ -90,7 +90,7 @@ bfad_debugfs_open_fwtrc(struct inode *inode, struct file *file)
        memset(fw_debug->debug_buffer, 0, fw_debug->buffer_len);
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
-       rc = bfa_debug_fwtrc(&bfad->bfa,
+       rc = bfa_ioc_debug_fwtrc(&bfad->bfa.ioc,
                        fw_debug->debug_buffer,
                        &fw_debug->buffer_len);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -134,7 +134,7 @@ bfad_debugfs_open_fwsave(struct inode *inode, struct file *file)
        memset(fw_debug->debug_buffer, 0, fw_debug->buffer_len);
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
-       rc = bfa_debug_fwsave(&bfad->bfa,
+       rc = bfa_ioc_debug_fwsave(&bfad->bfa.ioc,
                        fw_debug->debug_buffer,
                        &fw_debug->buffer_len);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -208,7 +208,7 @@ bfad_debugfs_read(struct file *file, char __user *buf,
        if (!debug || !debug->debug_buffer)
                return 0;
 
-       return memory_read_from_buffer(buf, nbytes, pos,
+       return simple_read_from_buffer(buf, nbytes, pos,
                                debug->debug_buffer, debug->buffer_len);
 }
 
@@ -254,7 +254,7 @@ bfad_debugfs_read_regrd(struct file *file, char __user *buf,
        if (!bfad->regdata)
                return 0;
 
-       rc = memory_read_from_buffer(buf, nbytes, pos,
+       rc = simple_read_from_buffer(buf, nbytes, pos,
                        bfad->regdata, bfad->reglen);
 
        if ((*pos + nbytes) >= bfad->reglen) {
@@ -279,15 +279,31 @@ bfad_debugfs_write_regrd(struct file *file, const char __user *buf,
        u32 *regbuf;
        void __iomem *rb, *reg_addr;
        unsigned long flags;
+       void *kern_buf;
 
-       rc = sscanf(buf, "%x:%x", &addr, &len);
+       kern_buf = kzalloc(nbytes, GFP_KERNEL);
+
+       if (!kern_buf) {
+               printk(KERN_INFO "bfad[%d]: Failed to allocate buffer\n",
+                               bfad->inst_no);
+               return -ENOMEM;
+       }
+
+       if (copy_from_user(kern_buf, (void  __user *)buf, nbytes)) {
+               kfree(kern_buf);
+               return -ENOMEM;
+       }
+
+       rc = sscanf(kern_buf, "%x:%x", &addr, &len);
        if (rc < 2) {
                printk(KERN_INFO
                        "bfad[%d]: %s failed to read user buf\n",
                        bfad->inst_no, __func__);
+               kfree(kern_buf);
                return -EINVAL;
        }
 
+       kfree(kern_buf);
        kfree(bfad->regdata);
        bfad->regdata = NULL;
        bfad->reglen = 0;
@@ -339,14 +355,30 @@ bfad_debugfs_write_regwr(struct file *file, const char __user *buf,
        int addr, val, rc;
        void __iomem *reg_addr;
        unsigned long flags;
+       void *kern_buf;
+
+       kern_buf = kzalloc(nbytes, GFP_KERNEL);
+
+       if (!kern_buf) {
+               printk(KERN_INFO "bfad[%d]: Failed to allocate buffer\n",
+                               bfad->inst_no);
+               return -ENOMEM;
+       }
+
+       if (copy_from_user(kern_buf, (void  __user *)buf, nbytes)) {
+               kfree(kern_buf);
+               return -ENOMEM;
+       }
 
-       rc = sscanf(buf, "%x:%x", &addr, &val);
+       rc = sscanf(kern_buf, "%x:%x", &addr, &val);
        if (rc < 2) {
                printk(KERN_INFO
                        "bfad[%d]: %s failed to read user buf\n",
                        bfad->inst_no, __func__);
+               kfree(kern_buf);
                return -EINVAL;
        }
+       kfree(kern_buf);
 
        addr &= BFA_REG_ADDRMSK(bfa); /* offset only 17 bit and word align */
 
@@ -359,7 +391,7 @@ bfad_debugfs_write_regwr(struct file *file, const char __user *buf,
                return -EINVAL;
        }
 
-       reg_addr = (u32 *) ((u8 *) bfa_ioc_bar0(ioc) + addr);
+       reg_addr = (bfa_ioc_bar0(ioc)) + addr;
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        writel(val, reg_addr);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
index 97f9b6c0937e75cf3a16762092ac46ac6f6cb890..7f9ea90254cd23f6153ab7c3974abc52e3e0f6b6 100644 (file)
 #ifndef __BFAD_DRV_H__
 #define __BFAD_DRV_H__
 
-#include "bfa_os_inc.h"
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/idr.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include <linux/bitops.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_transport_fc.h>
+#include <scsi/scsi_transport.h>
 
 #include "bfa_modules.h"
 #include "bfa_fcs.h"
@@ -39,7 +55,7 @@
 #ifdef BFA_DRIVER_VERSION
 #define BFAD_DRIVER_VERSION    BFA_DRIVER_VERSION
 #else
-#define BFAD_DRIVER_VERSION    "2.3.2.0"
+#define BFAD_DRIVER_VERSION    "2.3.2.3"
 #endif
 
 #define BFAD_PROTO_NAME FCPI_NAME
@@ -263,28 +279,21 @@ struct bfad_hal_comp {
  */
 #define nextLowerInt(x)                         \
 do {                                            \
-       int i;                                  \
+       int __i;                                  \
        (*x)--;                                 \
-       for (i = 1; i < (sizeof(int)*8); i <<= 1) \
-               (*x) = (*x) | (*x) >> i;        \
+       for (__i = 1; __i < (sizeof(int)*8); __i <<= 1) \
+               (*x) = (*x) | (*x) >> __i;      \
        (*x)++;                                 \
        (*x) = (*x) >> 1;                       \
 } while (0)
 
 
-#define list_remove_head(list, entry, type, member)            \
-do {                                                           \
-       entry = NULL;                                           \
-       if (!list_empty(list)) {                                \
-               entry = list_entry((list)->next, type, member); \
-               list_del_init(&entry->member);                  \
-       }                                                       \
+#define BFA_LOG(level, bfad, mask, fmt, arg...)                                \
+do {                                                                   \
+       if (((mask) == 4) || (level[1] <= '4'))                         \
+               dev_printk(level, &((bfad)->pcidev)->dev, fmt, ##arg);  \
 } while (0)
 
-#define list_get_first(list, type, member)                             \
-((list_empty(list)) ? NULL :                                           \
-       list_entry((list)->next, type, member))
-
 bfa_status_t   bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
                                  struct bfa_lport_cfg_s *port_cfg,
                                  struct device *dev);
@@ -316,8 +325,8 @@ void                bfad_debugfs_exit(struct bfad_port_s *port);
 
 void bfad_pci_remove(struct pci_dev *pdev);
 int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
-void bfad_os_rport_online_wait(struct bfad_s *bfad);
-int bfad_os_get_linkup_delay(struct bfad_s *bfad);
+void bfad_rport_online_wait(struct bfad_s *bfad);
+int bfad_get_linkup_delay(struct bfad_s *bfad);
 int bfad_install_msix_handler(struct bfad_s *bfad);
 
 extern struct idr bfad_im_port_index;
@@ -337,7 +346,7 @@ extern int  num_sgpgs;
 extern int      rport_del_timeout;
 extern int      bfa_lun_queue_depth;
 extern int      bfa_io_max_sge;
-extern int      log_level;
+extern int      bfa_log_level;
 extern int      ioc_auto_recover;
 extern int      bfa_linkup_delay;
 extern int      msix_disable_cb;
index 8daa716739d1bd6d2a6a4180c008161e7f148f27..53cea3d33351be0fe67efdfd21c61c521fdf21d6 100644 (file)
@@ -21,7 +21,6 @@
 
 #include "bfad_drv.h"
 #include "bfad_im.h"
-#include "bfa_cb_ioim.h"
 #include "bfa_fcs.h"
 
 BFA_TRC_FILE(LDRV, IM);
@@ -30,8 +29,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);
@@ -94,10 +92,10 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
                if (!cmnd->result && itnim &&
                         (bfa_lun_queue_depth > cmnd->device->queue_depth)) {
                        /* Queue depth adjustment for good status completion */
-                       bfad_os_ramp_up_qdepth(itnim, cmnd->device);
+                       bfad_ramp_up_qdepth(itnim, cmnd->device);
                } else if (cmnd->result == SAM_STAT_TASK_SET_FULL && itnim) {
                        /* qfull handling */
-                       bfad_os_handle_qfull(itnim, cmnd->device);
+                       bfad_handle_qfull(itnim, cmnd->device);
                }
        }
 
@@ -125,7 +123,7 @@ bfa_cb_ioim_good_comp(void *drv, struct bfad_ioim_s *dio)
                if (itnim_data) {
                        itnim = itnim_data->itnim;
                        if (itnim)
-                               bfad_os_ramp_up_qdepth(itnim, cmnd->device);
+                               bfad_ramp_up_qdepth(itnim, cmnd->device);
                }
        }
 
@@ -184,7 +182,7 @@ bfad_im_info(struct Scsi_Host *shost)
        bfa_get_adapter_model(bfa, model);
 
        memset(bfa_buf, 0, sizeof(bfa_buf));
-       if (ioc->ctdev)
+       if (ioc->ctdev && !ioc->fcmode)
                snprintf(bfa_buf, sizeof(bfa_buf),
                "Brocade FCOE Adapter, " "model: %s hwpath: %s driver: %s",
                 model, bfad->pci_name, BFAD_DRIVER_VERSION);
@@ -226,7 +224,8 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd)
        }
 
        bfa_trc(bfad, hal_io->iotag);
-       BFA_LOG(KERN_INFO, bfad, log_level, "scsi%d: abort cmnd %p iotag %x\n",
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
+               "scsi%d: abort cmnd %p iotag %x\n",
                im_port->shost->host_no, cmnd, hal_io->iotag);
        (void) bfa_ioim_abort(hal_io);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -242,7 +241,7 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd)
 
        cmnd->scsi_done(cmnd);
        bfa_trc(bfad, hal_io->iotag);
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "scsi%d: complete abort 0x%p iotag 0x%x\n",
                im_port->shost->host_no, cmnd, hal_io->iotag);
        return SUCCESS;
@@ -258,10 +257,11 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
        struct bfa_tskim_s *tskim;
        struct bfa_itnim_s *bfa_itnim;
        bfa_status_t    rc = BFA_STATUS_OK;
+       struct scsi_lun scsilun;
 
        tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
        if (!tskim) {
-               BFA_LOG(KERN_ERR, bfad, log_level,
+               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                        "target reset, fail to allocate tskim\n");
                rc = BFA_STATUS_FAILED;
                goto out;
@@ -274,7 +274,8 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
        cmnd->host_scribble = NULL;
        cmnd->SCp.Status = 0;
        bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
-       bfa_tskim_start(tskim, bfa_itnim, (lun_t)0,
+       memset(&scsilun, 0, sizeof(scsilun));
+       bfa_tskim_start(tskim, bfa_itnim, scsilun,
                            FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO);
 out:
        return rc;
@@ -301,6 +302,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
        int             rc = SUCCESS;
        unsigned long   flags;
        enum bfi_tskim_status task_status;
+       struct scsi_lun scsilun;
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        itnim = itnim_data->itnim;
@@ -312,7 +314,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
 
        tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
        if (!tskim) {
-               BFA_LOG(KERN_ERR, bfad, log_level,
+               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "LUN reset, fail to allocate tskim");
                spin_unlock_irqrestore(&bfad->bfad_lock, flags);
                rc = FAILED;
@@ -327,8 +329,8 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
        cmnd->SCp.ptr = (char *)&wq;
        cmnd->SCp.Status = 0;
        bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
-       bfa_tskim_start(tskim, bfa_itnim,
-                           bfad_int_to_lun(cmnd->device->lun),
+       int_to_scsilun(cmnd->device->lun, &scsilun);
+       bfa_tskim_start(tskim, bfa_itnim, scsilun,
                            FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
@@ -337,7 +339,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
 
        task_status = cmnd->SCp.Status >> 1;
        if (task_status != BFI_TSKIM_STS_OK) {
-               BFA_LOG(KERN_ERR, bfad, log_level,
+               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                        "LUN reset failure, status: %d\n", task_status);
                rc = FAILED;
        }
@@ -364,7 +366,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        for (i = 0; i < MAX_FCP_TARGET; i++) {
-               itnim = bfad_os_get_itnim(im_port, i);
+               itnim = bfad_get_itnim(im_port, i);
                if (itnim) {
                        cmnd->SCp.ptr = (char *)&wq;
                        rc = bfad_im_target_reset_send(bfad, cmnd, itnim);
@@ -381,7 +383,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
 
                        task_status = cmnd->SCp.Status >> 1;
                        if (task_status != BFI_TSKIM_STS_OK) {
-                               BFA_LOG(KERN_ERR, bfad, log_level,
+                               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                        "target reset failure,"
                                        " status: %d\n", task_status);
                                err_cnt++;
@@ -461,7 +463,7 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv)
        fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim);
        wwn2str(wwpn_str, wwpn);
        fcid2str(fcid_str, fcid);
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "ITNIM FREE scsi%d: FCID: %s WWPN: %s\n",
                port->im_port->shost->host_no,
                fcid_str, wwpn_str);
@@ -545,7 +547,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
 
        mutex_unlock(&bfad_mutex);
 
-       im_port->shost = bfad_os_scsi_host_alloc(im_port, bfad);
+       im_port->shost = bfad_scsi_host_alloc(im_port, bfad);
        if (!im_port->shost) {
                error = 1;
                goto out_free_idr;
@@ -571,7 +573,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
        }
 
        /* setup host fixed attribute if the lk supports */
-       bfad_os_fc_host_init(im_port);
+       bfad_fc_host_init(im_port);
 
        return 0;
 
@@ -590,7 +592,7 @@ void
 bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
 {
        bfa_trc(bfad, bfad->inst_no);
-       BFA_LOG(KERN_INFO, bfad, log_level, "Free scsi%d\n",
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Free scsi%d\n",
                        im_port->shost->host_no);
 
        fc_remove_host(im_port->shost);
@@ -682,7 +684,7 @@ bfad_im_probe(struct bfad_s *bfad)
        bfad->im = im;
        im->bfad = bfad;
 
-       if (bfad_os_thread_workq(bfad) != BFA_STATUS_OK) {
+       if (bfad_thread_workq(bfad) != BFA_STATUS_OK) {
                kfree(im);
                rc = BFA_STATUS_FAILED;
        }
@@ -695,14 +697,14 @@ void
 bfad_im_probe_undo(struct bfad_s *bfad)
 {
        if (bfad->im) {
-               bfad_os_destroy_workq(bfad->im);
+               bfad_destroy_workq(bfad->im);
                kfree(bfad->im);
                bfad->im = NULL;
        }
 }
 
 struct Scsi_Host *
-bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
+bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
 {
        struct scsi_host_template *sht;
 
@@ -717,7 +719,7 @@ bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
 }
 
 void
-bfad_os_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
+bfad_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
 {
        if (!(im_port->flags & BFAD_PORT_DELETE))
                flush_workqueue(bfad->im->drv_workq);
@@ -727,7 +729,7 @@ bfad_os_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
 }
 
 void
-bfad_os_destroy_workq(struct bfad_im_s *im)
+bfad_destroy_workq(struct bfad_im_s *im)
 {
        if (im && im->drv_workq) {
                flush_workqueue(im->drv_workq);
@@ -737,7 +739,7 @@ bfad_os_destroy_workq(struct bfad_im_s *im)
 }
 
 bfa_status_t
-bfad_os_thread_workq(struct bfad_s *bfad)
+bfad_thread_workq(struct bfad_s *bfad)
 {
        struct bfad_im_s      *im = bfad->im;
 
@@ -841,7 +843,7 @@ bfad_im_module_exit(void)
 }
 
 void
-bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
+bfad_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
 {
        struct scsi_device *tmp_sdev;
 
@@ -869,7 +871,7 @@ bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
 }
 
 void
-bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
+bfad_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
 {
        struct scsi_device *tmp_sdev;
 
@@ -883,7 +885,7 @@ bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
 }
 
 struct bfad_itnim_s *
-bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id)
+bfad_get_itnim(struct bfad_im_port_s *im_port, int id)
 {
        struct bfad_itnim_s   *itnim = NULL;
 
@@ -922,7 +924,7 @@ bfad_im_supported_speeds(struct bfa_s *bfa)
        if (!ioc_attr)
                return 0;
 
-       bfa_get_attr(bfa, ioc_attr);
+       bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
        if (ioc_attr->adapter_attr.max_speed == BFA_PORT_SPEED_8GBPS) {
                if (ioc_attr->adapter_attr.is_mezz) {
                        supported_speed |= FC_PORTSPEED_8GBIT |
@@ -944,7 +946,7 @@ bfad_im_supported_speeds(struct bfa_s *bfa)
 }
 
 void
-bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
+bfad_fc_host_init(struct bfad_im_port_s *im_port)
 {
        struct Scsi_Host *host = im_port->shost;
        struct bfad_s         *bfad = im_port->bfad;
@@ -988,7 +990,7 @@ bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim)
        rport_ids.port_name =
                cpu_to_be64(bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
        rport_ids.port_id =
-               bfa_os_hton3b(bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim));
+               bfa_hton3b(bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim));
        rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
 
        itnim->fc_rport = fc_rport =
@@ -1049,7 +1051,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
                        fcid2str(fcid_str, fcid);
                        list_add_tail(&itnim->list_entry,
                                &im_port->itnim_mapped_list);
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "ITNIM ONLINE Target: %d:0:%d "
                                "FCID: %s WWPN: %s\n",
                                im_port->shost->host_no,
@@ -1082,7 +1084,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
                        wwn2str(wwpn_str, wwpn);
                        fcid2str(fcid_str, fcid);
                        list_del(&itnim->list_entry);
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "ITNIM OFFLINE Target: %d:0:%d "
                                "FCID: %s WWPN: %s\n",
                                im_port->shost->host_no,
@@ -1120,7 +1122,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,8 +1189,10 @@ out_fail_cmd:
        return 0;
 }
 
+static DEF_SCSI_QCMD(bfad_im_queuecommand)
+
 void
-bfad_os_rport_online_wait(struct bfad_s *bfad)
+bfad_rport_online_wait(struct bfad_s *bfad)
 {
        int i;
        int rport_delay = 10;
@@ -1216,7 +1220,7 @@ bfad_os_rport_online_wait(struct bfad_s *bfad)
 }
 
 int
-bfad_os_get_linkup_delay(struct bfad_s *bfad)
+bfad_get_linkup_delay(struct bfad_s *bfad)
 {
        u8              nwwns = 0;
        wwn_t           wwns[BFA_PREBOOT_BOOTLUN_MAX];
index b038c0e089214d4017b8f235b5b6d8889aedcc5f..bfee63b16fa911cdbf7015d70b0698f57b8f2f8b 100644 (file)
@@ -117,17 +117,17 @@ struct bfad_im_s {
        char            drv_workq_name[KOBJ_NAME_LEN];
 };
 
-struct Scsi_Host *bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port,
+struct Scsi_Host *bfad_scsi_host_alloc(struct bfad_im_port_s *im_port,
                                struct bfad_s *);
-bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad);
-void bfad_os_destroy_workq(struct bfad_im_s *im);
-void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
-void bfad_os_scsi_host_free(struct bfad_s *bfad,
+bfa_status_t bfad_thread_workq(struct bfad_s *bfad);
+void bfad_destroy_workq(struct bfad_im_s *im);
+void bfad_fc_host_init(struct bfad_im_port_s *im_port);
+void bfad_scsi_host_free(struct bfad_s *bfad,
                                 struct bfad_im_port_s *im_port);
-void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim,
+void bfad_ramp_up_qdepth(struct bfad_itnim_s *itnim,
                                 struct scsi_device *sdev);
-void bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev);
-struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id);
+void bfad_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev);
+struct bfad_itnim_s *bfad_get_itnim(struct bfad_im_port_s *im_port, int id);
 
 extern struct scsi_host_template bfad_im_scsi_host_template;
 extern struct scsi_host_template bfad_im_vport_template;
index 58796d1284b70ae2b49b238d5b2e66737ca5d1a3..72b69a0c3b516eb01091ddb07a0599b889666969 100644 (file)
@@ -95,8 +95,8 @@ enum {
  */
 union bfi_addr_u {
        struct {
-               u32     addr_lo;
-               u32     addr_hi;
+               __be32  addr_lo;
+               __be32  addr_hi;
        } a32;
 };
 
@@ -104,7 +104,7 @@ union bfi_addr_u {
  * Scatter Gather Element
  */
 struct bfi_sge_s {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
        u32     flags:2,
                        rsvd:2,
                        sg_len:28;
@@ -399,7 +399,7 @@ union bfi_ioc_i2h_msg_u {
  */
 struct bfi_pbc_blun_s {
        wwn_t           tgt_pwwn;
-       lun_t           tgt_lun;
+       struct scsi_lun tgt_lun;
 };
 
 /*
index 6f03ed382c695ffd6ca47b71333a397727f5c833..39ad42b66b5b0a58cc666c092282db233f916d19 100644 (file)
 #define BFA_IOC1_HBEAT_REG               HOST_SEM2_INFO_REG
 #define BFA_IOC1_STATE_REG               HOST_SEM3_INFO_REG
 #define BFA_FW_USE_COUNT                 HOST_SEM4_INFO_REG
+#define BFA_IOC_FAIL_SYNC               HOST_SEM5_INFO_REG
 
 #define CPE_Q_DEPTH(__n) \
        (CPE_Q0_DEPTH + (__n) * (CPE_Q1_DEPTH - CPE_Q0_DEPTH))
index 62b86a4b0e4b99326750295116a520b53a3c3838..fc4ce4a5a183123d70f59b98851ba69ac5486698 100644 (file)
@@ -522,6 +522,7 @@ enum {
 #define BFA_IOC1_HBEAT_REG             HOST_SEM2_INFO_REG
 #define BFA_IOC1_STATE_REG             HOST_SEM3_INFO_REG
 #define BFA_FW_USE_COUNT                HOST_SEM4_INFO_REG
+#define BFA_IOC_FAIL_SYNC              HOST_SEM5_INFO_REG
 
 #define CPE_DEPTH_Q(__n) \
        (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0))
@@ -539,22 +540,30 @@ enum {
        (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0))
 #define RME_CI_PTR_Q(__n) \
        (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0))
-#define HQM_QSET_RXQ_DRBL_P0(__n) (HQM_QSET0_RXQ_DRBL_P0 + (__n) \
-       * (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
-#define HQM_QSET_TXQ_DRBL_P0(__n) (HQM_QSET0_TXQ_DRBL_P0 + (__n) \
-       * (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
-#define HQM_QSET_IB_DRBL_1_P0(__n) (HQM_QSET0_IB_DRBL_1_P0 + (__n) \
-       * (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
-#define HQM_QSET_IB_DRBL_2_P0(__n) (HQM_QSET0_IB_DRBL_2_P0 + (__n) \
-       * (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
-#define HQM_QSET_RXQ_DRBL_P1(__n) (HQM_QSET0_RXQ_DRBL_P1 + (__n) \
-       * (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
-#define HQM_QSET_TXQ_DRBL_P1(__n) (HQM_QSET0_TXQ_DRBL_P1 + (__n) \
-       * (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
-#define HQM_QSET_IB_DRBL_1_P1(__n) (HQM_QSET0_IB_DRBL_1_P1 + (__n) \
-       * (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
-#define HQM_QSET_IB_DRBL_2_P1(__n) (HQM_QSET0_IB_DRBL_2_P1 + (__n) \
-       * (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
+#define HQM_QSET_RXQ_DRBL_P0(__n) \
+       (HQM_QSET0_RXQ_DRBL_P0 + (__n) *        \
+       (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
+#define HQM_QSET_TXQ_DRBL_P0(__n) \
+       (HQM_QSET0_TXQ_DRBL_P0 + (__n) *        \
+       (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
+#define HQM_QSET_IB_DRBL_1_P0(__n) \
+       (HQM_QSET0_IB_DRBL_1_P0 + (__n) *       \
+       (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
+#define HQM_QSET_IB_DRBL_2_P0(__n) \
+       (HQM_QSET0_IB_DRBL_2_P0 + (__n) *       \
+       (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
+#define HQM_QSET_RXQ_DRBL_P1(__n) \
+       (HQM_QSET0_RXQ_DRBL_P1 + (__n) *        \
+       (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
+#define HQM_QSET_TXQ_DRBL_P1(__n) \
+       (HQM_QSET0_TXQ_DRBL_P1 + (__n) *        \
+       (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
+#define HQM_QSET_IB_DRBL_1_P1(__n) \
+       (HQM_QSET0_IB_DRBL_1_P1 + (__n) *       \
+       (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
+#define HQM_QSET_IB_DRBL_2_P1(__n) \
+       (HQM_QSET0_IB_DRBL_2_P1 + (__n) *       \
+       (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
 
 #define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
 #define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
index fa9f6fb9d45b0decc0920d88439b89c7bc37dbe5..19e888a57555accff45b49a870973146b9df7892 100644 (file)
@@ -47,10 +47,10 @@ struct bfi_iocfc_cfg_s {
         */
        union bfi_addr_u  req_cq_ba[BFI_IOC_MAX_CQS];
        union bfi_addr_u  req_shadow_ci[BFI_IOC_MAX_CQS];
-       u16    req_cq_elems[BFI_IOC_MAX_CQS];
+       __be16    req_cq_elems[BFI_IOC_MAX_CQS];
        union bfi_addr_u  rsp_cq_ba[BFI_IOC_MAX_CQS];
        union bfi_addr_u  rsp_shadow_pi[BFI_IOC_MAX_CQS];
-       u16    rsp_cq_elems[BFI_IOC_MAX_CQS];
+       __be16    rsp_cq_elems[BFI_IOC_MAX_CQS];
 
        union bfi_addr_u  stats_addr;   /*  DMA-able address for stats    */
        union bfi_addr_u  cfgrsp_addr;  /*  config response dma address  */
@@ -102,8 +102,8 @@ struct bfi_iocfc_set_intr_req_s {
        struct bfi_mhdr_s mh;           /*  common msg header           */
        u8              coalesce;       /*  enable intr coalescing      */
        u8              rsvd[3];
-       u16     delay;          /*  delay timer 0..1125us       */
-       u16     latency;        /*  latency timer 0..225us      */
+       __be16  delay;          /*  delay timer 0..1125us       */
+       __be16  latency;        /*  latency timer 0..225us      */
 };
 
 
@@ -188,7 +188,8 @@ struct bfi_fcport_rsp_s {
        struct bfi_mhdr_s  mh;          /*  common msg header               */
        u8                 status;      /*  port enable status              */
        u8                 rsvd[3];
-       u32        msgtag;      /*  msgtag for reply                */
+       struct  bfa_port_cfg_s port_cfg;/* port configuration   */
+       u32     msgtag;                 /* msgtag for reply     */
 };
 
 /*
@@ -202,7 +203,8 @@ struct bfi_fcport_enable_req_s {
        struct bfa_port_cfg_s port_cfg; /*  port configuration      */
        union bfi_addr_u   stats_dma_addr; /*  DMA address for stats        */
        u32        msgtag;      /*  msgtag for reply                */
-       u32        rsvd2;
+       u8      use_flash_cfg;  /* get prot cfg from flash */
+       u8      rsvd2[3];
 };
 
 /*
@@ -210,7 +212,7 @@ struct bfi_fcport_enable_req_s {
  */
 struct bfi_fcport_set_svc_params_req_s {
        struct bfi_mhdr_s  mh;          /*  msg header */
-       u16        tx_bbcredit; /*  Tx credits */
+       __be16     tx_bbcredit; /*  Tx credits */
        u16        rsvd;
 };
 
@@ -231,7 +233,7 @@ struct bfi_fcport_trunk_link_s {
        u8                      state;          /* bfa_trunk_link_state_t */
        u8                      speed;          /* bfa_port_speed_t */
        u8                      rsvd;
-       u32             deskew;
+       __be32          deskew;
 };
 
 #define BFI_FCPORT_MAX_LINKS   2
@@ -284,17 +286,17 @@ enum bfi_fcxp_i2h {
  */
 struct bfi_fcxp_send_req_s {
        struct bfi_mhdr_s  mh;          /*  Common msg header               */
-       u16     fcxp_tag;       /*  driver request tag              */
-       u16     max_frmsz;      /*  max send frame size     */
-       u16     vf_id;          /*  vsan tag if applicable          */
+       __be16  fcxp_tag;       /*  driver request tag              */
+       __be16  max_frmsz;      /*  max send frame size     */
+       __be16  vf_id;          /*  vsan tag if applicable          */
        u16     rport_fw_hndl;  /*  FW Handle for the remote port  */
        u8       class;         /*  FC class used for req/rsp       */
        u8       rsp_timeout;   /*  timeout in secs, 0-no response */
        u8       cts;           /*  continue sequence               */
        u8       lp_tag;        /*  lport tag                       */
        struct fchs_s   fchs;   /*  request FC header structure    */
-       u32     req_len;        /*  request payload length          */
-       u32     rsp_maxlen;     /*  max response length expected   */
+       __be32  req_len;        /*  request payload length          */
+       __be32  rsp_maxlen;     /*  max response length expected   */
        struct bfi_sge_s   req_sge[BFA_FCXP_MAX_SGES];  /*  request buf    */
        struct bfi_sge_s   rsp_sge[BFA_FCXP_MAX_SGES];  /*  response buf   */
 };
@@ -304,11 +306,11 @@ struct bfi_fcxp_send_req_s {
  */
 struct bfi_fcxp_send_rsp_s {
        struct bfi_mhdr_s  mh;          /*  Common msg header               */
-       u16     fcxp_tag;       /*  send request tag                */
+       __be16  fcxp_tag;       /*  send request tag                */
        u8       req_status;    /*  request status                  */
        u8       rsvd;
-       u32     rsp_len;        /*  actual response length          */
-       u32     residue_len;    /*  residual response length        */
+       __be32  rsp_len;        /*  actual response length          */
+       __be32  residue_len;    /*  residual response length        */
        struct fchs_s   fchs;   /*  response FC header structure   */
 };
 
@@ -325,7 +327,7 @@ enum bfi_uf_i2h {
 struct bfi_uf_buf_post_s {
        struct bfi_mhdr_s  mh;          /*  Common msg header           */
        u16     buf_tag;        /*  buffer tag                  */
-       u16     buf_len;        /*  total buffer length */
+       __be16  buf_len;        /*  total buffer length */
        struct bfi_sge_s   sge[BFA_UF_MAX_SGES]; /*  buffer DMA SGEs    */
 };
 
@@ -340,6 +342,7 @@ struct bfi_uf_frm_rcvd_s {
 enum bfi_lps_h2i_msgs {
        BFI_LPS_H2I_LOGIN_REQ   = 1,
        BFI_LPS_H2I_LOGOUT_REQ  = 2,
+       BFI_LPS_H2I_N2N_PID_REQ = 3,
 };
 
 enum bfi_lps_i2h_msgs {
@@ -352,7 +355,7 @@ struct bfi_lps_login_req_s {
        struct bfi_mhdr_s  mh;          /*  common msg header           */
        u8              lp_tag;
        u8              alpa;
-       u16     pdu_size;
+       __be16          pdu_size;
        wwn_t           pwwn;
        wwn_t           nwwn;
        u8              fdisc;
@@ -368,7 +371,7 @@ struct bfi_lps_login_rsp_s {
        u8              lsrjt_expl;
        wwn_t           port_name;
        wwn_t           node_name;
-       u16     bb_credit;
+       __be16          bb_credit;
        u8              f_port;
        u8              npiv_en;
        u32     lp_pid:24;
@@ -399,10 +402,17 @@ struct bfi_lps_cvl_event_s {
        u8              rsvd[3];
 };
 
+struct bfi_lps_n2n_pid_req_s {
+       struct bfi_mhdr_s       mh;     /*  common msg header           */
+       u8      lp_tag;
+       u32     lp_pid:24;
+};
+
 union bfi_lps_h2i_msg_u {
        struct bfi_mhdr_s               *msg;
        struct bfi_lps_login_req_s      *login_req;
        struct bfi_lps_logout_req_s     *logout_req;
+       struct bfi_lps_n2n_pid_req_s    *n2n_pid_req;
 };
 
 union bfi_lps_i2h_msg_u {
@@ -427,7 +437,7 @@ enum bfi_rport_i2h_msgs {
 struct bfi_rport_create_req_s {
        struct bfi_mhdr_s  mh;          /*  common msg header           */
        u16     bfa_handle;     /*  host rport handle           */
-       u16     max_frmsz;      /*  max rcv pdu size            */
+       __be16  max_frmsz;      /*  max rcv pdu size            */
        u32     pid:24, /*  remote port ID              */
                lp_tag:8;       /*  local port tag              */
        u32     local_pid:24,   /*  local port ID               */
@@ -583,7 +593,7 @@ struct bfi_ioim_dif_s {
  */
 struct bfi_ioim_req_s {
        struct bfi_mhdr_s  mh;          /*  Common msg header            */
-       u16     io_tag;         /*  I/O tag                      */
+       __be16  io_tag;         /*  I/O tag                      */
        u16     rport_hdl;      /*  itnim/rport firmware handle */
        struct fcp_cmnd_s       cmnd;   /*  IO request info     */
 
@@ -689,7 +699,7 @@ enum bfi_ioim_status {
  */
 struct bfi_ioim_rsp_s {
        struct bfi_mhdr_s       mh;     /*  common msg header           */
-       u16     io_tag;         /*  completed IO tag             */
+       __be16  io_tag;         /*  completed IO tag             */
        u16     bfa_rport_hndl; /*  releated rport handle        */
        u8      io_status;      /*  IO completion status         */
        u8      reuse_io_tag;   /*  IO tag can be reused        */
@@ -698,13 +708,13 @@ struct bfi_ioim_rsp_s {
        u8              sns_len;        /*  scsi sense length            */
        u8              resid_flags;    /*  IO residue flags             */
        u8              rsvd_a;
-       u32     residue;        /*  IO residual length in bytes */
+       __be32  residue;        /*  IO residual length in bytes */
        u32     rsvd_b[3];
 };
 
 struct bfi_ioim_abort_req_s {
        struct bfi_mhdr_s  mh;  /*  Common msg header  */
-       u16     io_tag; /*  I/O tag     */
+       __be16  io_tag; /*  I/O tag     */
        u16     abort_tag;      /*  unique request tag */
 };
 
@@ -723,9 +733,9 @@ enum bfi_tskim_i2h {
 
 struct bfi_tskim_req_s {
        struct bfi_mhdr_s  mh;  /*  Common msg header   */
-       u16     tsk_tag;        /*  task management tag */
+       __be16  tsk_tag;        /*  task management tag */
        u16     itn_fhdl;       /*  itn firmware handle */
-       lun_t   lun;    /*  LU number   */
+       struct  scsi_lun lun;   /*  LU number   */
        u8      tm_flags;       /*  see enum fcp_tm_cmnd        */
        u8      t_secs; /*  Timeout value in seconds    */
        u8      rsvd[2];
@@ -733,7 +743,7 @@ struct bfi_tskim_req_s {
 
 struct bfi_tskim_abortreq_s {
        struct bfi_mhdr_s  mh;  /*  Common msg header   */
-       u16     tsk_tag;        /*  task management tag */
+       __be16  tsk_tag;        /*  task management tag */
        u16     rsvd;
 };
 
@@ -755,7 +765,7 @@ enum bfi_tskim_status {
 
 struct bfi_tskim_rsp_s {
        struct bfi_mhdr_s  mh;          /*  Common msg header            */
-       u16     tsk_tag;        /*  task mgmt cmnd tag           */
+       __be16  tsk_tag;        /*  task mgmt cmnd tag           */
        u8      tsk_status;     /*  @ref bfi_tskim_status */
        u8      rsvd;
 };
index 1b6f86b2482d6cf7c2e81faf56c555dfa14547d6..30e6bdbd65afaeccc07295ec18b513d9262a4751 100644 (file)
@@ -1,12 +1,13 @@
 /* 57xx_iscsi_constants.h: Broadcom NetXtreme II iSCSI HSI
  *
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation.
  *
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
  */
 #ifndef __57XX_ISCSI_CONSTANTS_H_
 #define __57XX_ISCSI_CONSTANTS_H_
index 36af1afef9b6651da90d6583e1bac1746332ef88..dad6c8a34317211ba7b0b3c9c72116c0c40f7360 100644 (file)
@@ -1,12 +1,13 @@
 /* 57xx_iscsi_hsi.h: Broadcom NetXtreme II iSCSI HSI.
  *
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation.
  *
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
  */
 #ifndef __57XX_ISCSI_HSI_LINUX_LE__
 #define __57XX_ISCSI_HSI_LINUX_LE__
index a44b1b33fa18badd49bb92831e82300385f224cb..e1ca5fe7e6bb432f753d90192b1544a1fa805c42 100644 (file)
@@ -1,6 +1,6 @@
 /* bnx2i.h: Broadcom NetXtreme II iSCSI driver.
  *
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
  * Copyright (c) 2007, 2008 Red Hat, Inc.  All rights reserved.
  * Copyright (c) 2007, 2008 Mike Christie
  *
@@ -9,6 +9,7 @@
  * the Free Software Foundation.
  *
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
  */
 
 #ifndef _BNX2I_H_
@@ -649,6 +650,7 @@ enum {
        EP_STATE_OFLD_FAILED            = 0x8000000,
        EP_STATE_CONNECT_FAILED         = 0x10000000,
        EP_STATE_DISCONN_TIMEDOUT       = 0x20000000,
+       EP_STATE_OFLD_FAILED_CID_BUSY   = 0x80000000,
 };
 
 /**
@@ -717,14 +719,11 @@ extern struct device_attribute *bnx2i_dev_attributes[];
  * Function Prototypes
  */
 extern void bnx2i_identify_device(struct bnx2i_hba *hba);
-extern void bnx2i_register_device(struct bnx2i_hba *hba);
 
 extern void bnx2i_ulp_init(struct cnic_dev *dev);
 extern void bnx2i_ulp_exit(struct cnic_dev *dev);
 extern void bnx2i_start(void *handle);
 extern void bnx2i_stop(void *handle);
-extern void bnx2i_reg_dev_all(void);
-extern void bnx2i_unreg_dev_all(void);
 extern struct bnx2i_hba *get_adapter_list_head(void);
 
 struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba,
@@ -761,11 +760,11 @@ extern int bnx2i_send_iscsi_logout(struct bnx2i_conn *conn,
                                   struct iscsi_task *mtask);
 extern void bnx2i_send_cmd_cleanup_req(struct bnx2i_hba *hba,
                                       struct bnx2i_cmd *cmd);
-extern void bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba,
-                                    struct bnx2i_endpoint *ep);
-extern void bnx2i_update_iscsi_conn(struct iscsi_conn *conn);
-extern void bnx2i_send_conn_destroy(struct bnx2i_hba *hba,
+extern int bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba,
                                    struct bnx2i_endpoint *ep);
+extern void bnx2i_update_iscsi_conn(struct iscsi_conn *conn);
+extern int bnx2i_send_conn_destroy(struct bnx2i_hba *hba,
+                                  struct bnx2i_endpoint *ep);
 
 extern int bnx2i_alloc_qp_resc(struct bnx2i_hba *hba,
                               struct bnx2i_endpoint *ep);
index 8d9dbb33972f2d63cd5d7f336f6e4afdbb8e2ca0..93753692c37abd994fa78a35cec22d94c7f95993 100644 (file)
@@ -1,6 +1,6 @@
 /* bnx2i_hwi.c: Broadcom NetXtreme II iSCSI driver.
  *
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
  * Copyright (c) 2007, 2008 Red Hat, Inc.  All rights reserved.
  * Copyright (c) 2007, 2008 Mike Christie
  *
@@ -9,6 +9,7 @@
  * the Free Software Foundation.
  *
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
  */
 
 #include <linux/gfp.h>
@@ -385,6 +386,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
        struct bnx2i_cmd *bnx2i_cmd;
        struct bnx2i_tmf_request *tmfabort_wqe;
        u32 dword;
+       u32 scsi_lun[2];
 
        bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
        tmfabort_hdr = (struct iscsi_tm *)mtask->hdr;
@@ -426,7 +428,10 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
        default:
                tmfabort_wqe->ref_itt = RESERVED_ITT;
        }
-       memcpy(tmfabort_wqe->lun, tmfabort_hdr->lun, sizeof(struct scsi_lun));
+       memcpy(scsi_lun, tmfabort_hdr->lun, sizeof(struct scsi_lun));
+       tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]);
+       tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]);
+
        tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn);
 
        tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
@@ -697,10 +702,11 @@ void bnx2i_send_cmd_cleanup_req(struct bnx2i_hba *hba, struct bnx2i_cmd *cmd)
  * this routine prepares and posts CONN_OFLD_REQ1/2 KWQE to initiate
  *     iscsi connection context clean-up process
  */
-void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
+int bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
 {
        struct kwqe *kwqe_arr[2];
        struct iscsi_kwqe_conn_destroy conn_cleanup;
+       int rc = -EINVAL;
 
        memset(&conn_cleanup, 0x00, sizeof(struct iscsi_kwqe_conn_destroy));
 
@@ -717,7 +723,9 @@ void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
 
        kwqe_arr[0] = (struct kwqe *) &conn_cleanup;
        if (hba->cnic && hba->cnic->submit_kwqes)
-               hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 1);
+               rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 1);
+
+       return rc;
 }
 
 
@@ -728,8 +736,8 @@ void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
  *
  * 5706/5708/5709 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE
  */
-static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
-                                         struct bnx2i_endpoint *ep)
+static int bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
+                                        struct bnx2i_endpoint *ep)
 {
        struct kwqe *kwqe_arr[2];
        struct iscsi_kwqe_conn_offload1 ofld_req1;
@@ -737,6 +745,7 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
        dma_addr_t dma_addr;
        int num_kwqes = 2;
        u32 *ptbl;
+       int rc = -EINVAL;
 
        ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1;
        ofld_req1.hdr.flags =
@@ -774,7 +783,9 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
        ofld_req2.num_additional_wqes = 0;
 
        if (hba->cnic && hba->cnic->submit_kwqes)
-               hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
+               rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
+
+       return rc;
 }
 
 
@@ -785,8 +796,8 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
  *
  * 57710 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE
  */
-static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
-                                          struct bnx2i_endpoint *ep)
+static int bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
+                                         struct bnx2i_endpoint *ep)
 {
        struct kwqe *kwqe_arr[5];
        struct iscsi_kwqe_conn_offload1 ofld_req1;
@@ -795,6 +806,7 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
        dma_addr_t dma_addr;
        int num_kwqes = 2;
        u32 *ptbl;
+       int rc = -EINVAL;
 
        ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1;
        ofld_req1.hdr.flags =
@@ -840,7 +852,9 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
        num_kwqes += 1;
 
        if (hba->cnic && hba->cnic->submit_kwqes)
-               hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
+               rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
+
+       return rc;
 }
 
 /**
@@ -851,12 +865,16 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
  *
  * this routine prepares and posts CONN_OFLD_REQ1/2 KWQE
  */
-void bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
+int bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
 {
+       int rc;
+
        if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
-               bnx2i_5771x_send_conn_ofld_req(hba, ep);
+               rc = bnx2i_5771x_send_conn_ofld_req(hba, ep);
        else
-               bnx2i_570x_send_conn_ofld_req(hba, ep);
+               rc = bnx2i_570x_send_conn_ofld_req(hba, ep);
+
+       return rc;
 }
 
 
@@ -1513,7 +1531,7 @@ static void bnx2i_process_nopin_local_cmpl(struct iscsi_session *session,
        task = iscsi_itt_to_task(conn,
                                 nop_in->itt & ISCSI_NOP_IN_MSG_INDEX);
        if (task)
-               iscsi_put_task(task);
+               __iscsi_put_task(task);
        spin_unlock(&session->lock);
 }
 
@@ -1549,11 +1567,9 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
        struct iscsi_task *task;
        struct bnx2i_nop_in_msg *nop_in;
        struct iscsi_nopin *hdr;
-       u32 itt;
        int tgt_async_nop = 0;
 
        nop_in = (struct bnx2i_nop_in_msg *)cqe;
-       itt = nop_in->itt & ISCSI_NOP_IN_MSG_INDEX;
 
        spin_lock(&session->lock);
        hdr = (struct iscsi_nopin *)&bnx2i_conn->gen_pdu.resp_hdr;
@@ -1563,7 +1579,7 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
        hdr->exp_cmdsn = cpu_to_be32(nop_in->exp_cmd_sn);
        hdr->ttt = cpu_to_be32(nop_in->ttt);
 
-       if (itt == (u16) RESERVED_ITT) {
+       if (nop_in->itt == (u16) RESERVED_ITT) {
                bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
                hdr->itt = RESERVED_ITT;
                tgt_async_nop = 1;
@@ -1571,7 +1587,8 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
        }
 
        /* this is a response to one of our nop-outs */
-       task = iscsi_itt_to_task(conn, itt);
+       task = iscsi_itt_to_task(conn,
+                        (itt_t) (nop_in->itt & ISCSI_NOP_IN_MSG_INDEX));
        if (task) {
                hdr->flags = ISCSI_FLAG_CMD_FINAL;
                hdr->itt = task->hdr->itt;
@@ -1721,9 +1738,18 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
                if (nopin->cq_req_sn != qp->cqe_exp_seq_sn)
                        break;
 
-               if (unlikely(test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx)))
+               if (unlikely(test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx))) {
+                       if (nopin->op_code == ISCSI_OP_NOOP_IN &&
+                           nopin->itt == (u16) RESERVED_ITT) {
+                               printk(KERN_ALERT "bnx2i: Unsolicited "
+                                       "NOP-In detected for suspended "
+                                       "connection dev=%s!\n",
+                                       bnx2i_conn->hba->netdev->name);
+                               bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
+                               goto cqe_out;
+                       }
                        break;
-
+               }
                tgt_async_msg = 0;
 
                switch (nopin->op_code) {
@@ -1770,10 +1796,9 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
                        printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n",
                                          nopin->op_code);
                }
-
                if (!tgt_async_msg)
                        bnx2i_conn->ep->num_active_cmds--;
-
+cqe_out:
                /* clear out in production version only, till beta keep opcode
                 * field intact, will be helpful in debugging (context dump)
                 * nopin->op_code = 0;
@@ -2154,11 +2179,24 @@ static void bnx2i_process_ofld_cmpl(struct bnx2i_hba *hba,
        }
 
        if (ofld_kcqe->completion_status) {
+               ep->state = EP_STATE_OFLD_FAILED;
                if (ofld_kcqe->completion_status ==
                    ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE)
-                       printk(KERN_ALERT "bnx2i: unable to allocate"
-                                         " iSCSI context resources\n");
-               ep->state = EP_STATE_OFLD_FAILED;
+                       printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - unable "
+                               "to allocate iSCSI context resources\n",
+                               hba->netdev->name);
+               else if (ofld_kcqe->completion_status ==
+                        ISCSI_KCQE_COMPLETION_STATUS_INVALID_OPCODE)
+                       printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - invalid "
+                               "opcode\n", hba->netdev->name);
+               else if (ofld_kcqe->completion_status ==
+                       ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY)
+                       /* error status code valid only for 5771x chipset */
+                       ep->state = EP_STATE_OFLD_FAILED_CID_BUSY;
+               else
+                       printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - invalid "
+                               "error code %d\n", hba->netdev->name,
+                               ofld_kcqe->completion_status);
        } else {
                ep->state = EP_STATE_OFLD_COMPL;
                cid_addr = ofld_kcqe->iscsi_conn_context_id;
@@ -2339,10 +2377,14 @@ static void bnx2i_cm_remote_close(struct cnic_sock *cm_sk)
 static void bnx2i_cm_remote_abort(struct cnic_sock *cm_sk)
 {
        struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context;
+       u32 old_state = ep->state;
 
        ep->state = EP_STATE_TCP_RST_RCVD;
-       if (ep->conn)
-               bnx2i_recovery_que_add_conn(ep->hba, ep->conn);
+       if (old_state == EP_STATE_DISCONN_START)
+               wake_up_interruptible(&ep->ofld_wait);
+       else
+               if (ep->conn)
+                       bnx2i_recovery_que_add_conn(ep->hba, ep->conn);
 }
 
 
index 50c2aa3b8eb1dfa7408dba3963ac39cc9475386e..72a7b2d4a439e8f0740a91607daffe4a922c1a62 100644 (file)
@@ -1,6 +1,6 @@
 /* bnx2i.c: Broadcom NetXtreme II iSCSI driver.
  *
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
  * Copyright (c) 2007, 2008 Red Hat, Inc.  All rights reserved.
  * Copyright (c) 2007, 2008 Mike Christie
  *
@@ -9,6 +9,7 @@
  * the Free Software Foundation.
  *
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
  */
 
 #include "bnx2i.h"
@@ -17,8 +18,8 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
 static u32 adapter_count;
 
 #define DRV_MODULE_NAME                "bnx2i"
-#define DRV_MODULE_VERSION     "2.1.3"
-#define DRV_MODULE_RELDATE     "Aug 10, 2010"
+#define DRV_MODULE_VERSION     "2.6.2.2"
+#define DRV_MODULE_RELDATE     "Nov 23, 2010"
 
 static char version[] __devinitdata =
                "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
@@ -65,8 +66,6 @@ MODULE_PARM_DESC(rq_size, "Configure RQ size");
 
 u64 iscsi_error_mask = 0x00;
 
-static void bnx2i_unreg_one_device(struct bnx2i_hba *hba) ;
-
 
 /**
  * bnx2i_identify_device - identifies NetXtreme II device type
@@ -211,13 +210,24 @@ void bnx2i_stop(void *handle)
 {
        struct bnx2i_hba *hba = handle;
        int conns_active;
+       int wait_delay = 1 * HZ;
 
        /* check if cleanup happened in GOING_DOWN context */
-       if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN,
-                               &hba->adapter_state))
+       if (!test_and_set_bit(ADAPTER_STATE_GOING_DOWN,
+                             &hba->adapter_state)) {
                iscsi_host_for_each_session(hba->shost,
                                            bnx2i_drop_session);
-
+               wait_delay = hba->hba_shutdown_tmo;
+       }
+       /* Wait for inflight offload connection tasks to complete before
+        * proceeding. Forcefully terminate all connection recovery in
+        * progress at the earliest, either in bind(), send_pdu(LOGIN),
+        * or conn_start()
+        */
+       wait_event_interruptible_timeout(hba->eh_wait,
+                                        (list_empty(&hba->ep_ofld_list) &&
+                                        list_empty(&hba->ep_destroy_list)),
+                                        10 * HZ);
        /* Wait for all endpoints to be torn down, Chip will be reset once
         *  control returns to network driver. So it is required to cleanup and
         * release all connection resources before returning from this routine.
@@ -226,7 +236,7 @@ void bnx2i_stop(void *handle)
                conns_active = hba->ofld_conns_active;
                wait_event_interruptible_timeout(hba->eh_wait,
                                (hba->ofld_conns_active != conns_active),
-                               hba->hba_shutdown_tmo);
+                               wait_delay);
                if (hba->ofld_conns_active == conns_active)
                        break;
        }
@@ -235,88 +245,10 @@ void bnx2i_stop(void *handle)
        /* This flag should be cleared last so that ep_disconnect() gracefully
         * cleans up connection context
         */
+       clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
        clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
 }
 
-/**
- * bnx2i_register_device - register bnx2i adapter instance with the cnic driver
- * @hba:       Adapter instance to register
- *
- * registers bnx2i adapter instance with the cnic driver while holding the
- *     adapter structure lock
- */
-void bnx2i_register_device(struct bnx2i_hba *hba)
-{
-       int rc;
-
-       if (test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state) ||
-           test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
-               return;
-       }
-
-       rc = hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba);
-
-       if (!rc)
-               set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
-}
-
-
-/**
- * bnx2i_reg_dev_all - registers all adapter instances with the cnic driver
- *
- * registers all bnx2i adapter instances with the cnic driver while holding
- *     the global resource lock
- */
-void bnx2i_reg_dev_all(void)
-{
-       struct bnx2i_hba *hba, *temp;
-
-       mutex_lock(&bnx2i_dev_lock);
-       list_for_each_entry_safe(hba, temp, &adapter_list, link)
-               bnx2i_register_device(hba);
-       mutex_unlock(&bnx2i_dev_lock);
-}
-
-
-/**
- * bnx2i_unreg_one_device - unregister adapter instance with the cnic driver
- * @hba:       Adapter instance to unregister
- *
- * registers bnx2i adapter instance with the cnic driver while holding
- *     the adapter structure lock
- */
-static void bnx2i_unreg_one_device(struct bnx2i_hba *hba)
-{
-       if (hba->ofld_conns_active ||
-           !test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic) ||
-           test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state))
-               return;
-
-       hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
-
-       /* ep_disconnect could come before NETDEV_DOWN, driver won't
-        * see NETDEV_DOWN as it already unregistered itself.
-        */
-       hba->adapter_state = 0;
-       clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
-}
-
-/**
- * bnx2i_unreg_dev_all - unregisters all bnx2i instances with the cnic driver
- *
- * unregisters all bnx2i adapter instances with the cnic driver while holding
- *     the global resource lock
- */
-void bnx2i_unreg_dev_all(void)
-{
-       struct bnx2i_hba *hba, *temp;
-
-       mutex_lock(&bnx2i_dev_lock);
-       list_for_each_entry_safe(hba, temp, &adapter_list, link)
-               bnx2i_unreg_one_device(hba);
-       mutex_unlock(&bnx2i_dev_lock);
-}
-
 
 /**
  * bnx2i_init_one - initialize an adapter instance and allocate memory resources
index fb50efbce0870e534ecac9342090d0778bec4149..f0dce26593eb9783bd482f2a9ad56c49e606c87a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver.
  *
- * Copyright (c) 2006 - 2009 Broadcom Corporation
+ * Copyright (c) 2006 - 2010 Broadcom Corporation
  * Copyright (c) 2007, 2008 Red Hat, Inc.  All rights reserved.
  * Copyright (c) 2007, 2008 Mike Christie
  *
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  *
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
  */
 
 #include <linux/slab.h>
@@ -411,7 +412,9 @@ static void bnx2i_free_ep(struct iscsi_endpoint *ep)
        bnx2i_ep->state = EP_STATE_IDLE;
        bnx2i_ep->hba->ofld_conns_active--;
 
-       bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid);
+       if (bnx2i_ep->ep_iscsi_cid != (u16) -1)
+               bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid);
+
        if (bnx2i_ep->conn) {
                bnx2i_ep->conn->ep = NULL;
                bnx2i_ep->conn = NULL;
@@ -1383,6 +1386,12 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
        ep = iscsi_lookup_endpoint(transport_fd);
        if (!ep)
                return -EINVAL;
+       /*
+        * Forcefully terminate all in progress connection recovery at the
+        * earliest, either in bind(), send_pdu(LOGIN), or conn_start()
+        */
+       if (bnx2i_adapter_ready(hba))
+               return -EIO;
 
        bnx2i_ep = ep->dd_data;
        if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) ||
@@ -1404,7 +1413,6 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
                                  hba->netdev->name);
                return -EEXIST;
        }
-
        bnx2i_ep->conn = bnx2i_conn;
        bnx2i_conn->ep = bnx2i_ep;
        bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid;
@@ -1461,21 +1469,28 @@ static int bnx2i_conn_get_param(struct iscsi_cls_conn *cls_conn,
        struct bnx2i_conn *bnx2i_conn = conn->dd_data;
        int len = 0;
 
+       if (!(bnx2i_conn && bnx2i_conn->ep && bnx2i_conn->ep->hba))
+               goto out;
+
        switch (param) {
        case ISCSI_PARAM_CONN_PORT:
-               if (bnx2i_conn->ep)
+               mutex_lock(&bnx2i_conn->ep->hba->net_dev_lock);
+               if (bnx2i_conn->ep->cm_sk)
                        len = sprintf(buf, "%hu\n",
                                      bnx2i_conn->ep->cm_sk->dst_port);
+               mutex_unlock(&bnx2i_conn->ep->hba->net_dev_lock);
                break;
        case ISCSI_PARAM_CONN_ADDRESS:
-               if (bnx2i_conn->ep)
+               mutex_lock(&bnx2i_conn->ep->hba->net_dev_lock);
+               if (bnx2i_conn->ep->cm_sk)
                        len = sprintf(buf, "%pI4\n",
                                      &bnx2i_conn->ep->cm_sk->dst_ip);
+               mutex_unlock(&bnx2i_conn->ep->hba->net_dev_lock);
                break;
        default:
                return iscsi_conn_get_param(cls_conn, param, buf);
        }
-
+out:
        return len;
 }
 
@@ -1599,8 +1614,6 @@ static struct bnx2i_hba *bnx2i_check_route(struct sockaddr *dst_addr)
        struct bnx2i_hba *hba;
        struct cnic_dev *cnic = NULL;
 
-       bnx2i_reg_dev_all();
-
        hba = get_adapter_list_head();
        if (hba && hba->cnic)
                cnic = hba->cnic->cm_select_dev(desti, CNIC_ULP_ISCSI);
@@ -1640,18 +1653,26 @@ no_nx2_route:
 static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
                                 struct bnx2i_endpoint *ep)
 {
-       if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic))
+       if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic) && ep->cm_sk)
                hba->cnic->cm_destroy(ep->cm_sk);
 
-       if (test_bit(ADAPTER_STATE_GOING_DOWN, &ep->hba->adapter_state))
-               ep->state = EP_STATE_DISCONN_COMPL;
-
        if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type) &&
            ep->state == EP_STATE_DISCONN_TIMEDOUT) {
-               printk(KERN_ALERT "bnx2i - ERROR - please submit GRC Dump,"
-                                 " NW/PCIe trace, driver msgs to developers"
-                                 " for analysis\n");
-               return 1;
+               if (ep->conn && ep->conn->cls_conn &&
+                   ep->conn->cls_conn->dd_data) {
+                       struct iscsi_conn *conn = ep->conn->cls_conn->dd_data;
+
+                       /* Must suspend all rx queue activity for this ep */
+                       set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
+               }
+               /* CONN_DISCONNECT timeout may or may not be an issue depending
+                * on what transcribed in TCP layer, different targets behave
+                * differently
+                */
+               printk(KERN_ALERT "bnx2i (%s): - WARN - CONN_DISCON timed out, "
+                                 "please submit GRC Dump, NW/PCIe trace, "
+                                 "driver msgs to developers for analysis\n",
+                                 hba->netdev->name);
        }
 
        ep->state = EP_STATE_CLEANUP_START;
@@ -1664,7 +1685,9 @@ static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
        bnx2i_ep_destroy_list_add(hba, ep);
 
        /* destroy iSCSI context, wait for it to complete */
-       bnx2i_send_conn_destroy(hba, ep);
+       if (bnx2i_send_conn_destroy(hba, ep))
+               ep->state = EP_STATE_CLEANUP_CMPL;
+
        wait_event_interruptible(ep->ofld_wait,
                                 (ep->state != EP_STATE_CLEANUP_START));
 
@@ -1711,8 +1734,6 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
        if (shost) {
                /* driver is given scsi host to work with */
                hba = iscsi_host_priv(shost);
-               /* Register the device with cnic if not already done so */
-               bnx2i_register_device(hba);
        } else
                /*
                 * check if the given destination can be reached through
@@ -1720,13 +1741,17 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
                 */
                hba = bnx2i_check_route(dst_addr);
 
-       if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) {
+       if (!hba) {
                rc = -EINVAL;
                goto nohba;
        }
+       mutex_lock(&hba->net_dev_lock);
 
+       if (bnx2i_adapter_ready(hba) || !hba->cid_que.cid_free_cnt) {
+               rc = -EPERM;
+               goto check_busy;
+       }
        cnic = hba->cnic;
-       mutex_lock(&hba->net_dev_lock);
        ep = bnx2i_alloc_ep(hba);
        if (!ep) {
                rc = -ENOMEM;
@@ -1734,23 +1759,21 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
        }
        bnx2i_ep = ep->dd_data;
 
-       if (bnx2i_adapter_ready(hba)) {
-               rc = -EPERM;
-               goto net_if_down;
-       }
-
        bnx2i_ep->num_active_cmds = 0;
        iscsi_cid = bnx2i_alloc_iscsi_cid(hba);
        if (iscsi_cid == -1) {
-               printk(KERN_ALERT "alloc_ep: unable to allocate iscsi cid\n");
+               printk(KERN_ALERT "bnx2i (%s): alloc_ep - unable to allocate "
+                       "iscsi cid\n", hba->netdev->name);
                rc = -ENOMEM;
-               goto iscsi_cid_err;
+               bnx2i_free_ep(ep);
+               goto check_busy;
        }
        bnx2i_ep->hba_age = hba->age;
 
        rc = bnx2i_alloc_qp_resc(hba, bnx2i_ep);
        if (rc != 0) {
-               printk(KERN_ALERT "bnx2i: ep_conn, alloc QP resc error\n");
+               printk(KERN_ALERT "bnx2i (%s): ep_conn - alloc QP resc error"
+                       "\n", hba->netdev->name);
                rc = -ENOMEM;
                goto qp_resc_err;
        }
@@ -1765,7 +1788,18 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
        bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep;
        add_timer(&bnx2i_ep->ofld_timer);
 
-       bnx2i_send_conn_ofld_req(hba, bnx2i_ep);
+       if (bnx2i_send_conn_ofld_req(hba, bnx2i_ep)) {
+               if (bnx2i_ep->state == EP_STATE_OFLD_FAILED_CID_BUSY) {
+                       printk(KERN_ALERT "bnx2i (%s): iscsi cid %d is busy\n",
+                               hba->netdev->name, bnx2i_ep->ep_iscsi_cid);
+                       rc = -EBUSY;
+               } else
+                       rc = -ENOSPC;
+               printk(KERN_ALERT "bnx2i (%s): unable to send conn offld kwqe"
+                       "\n", hba->netdev->name);
+               bnx2i_ep_ofld_list_del(hba, bnx2i_ep);
+               goto conn_failed;
+       }
 
        /* Wait for CNIC hardware to setup conn context and return 'cid' */
        wait_event_interruptible(bnx2i_ep->ofld_wait,
@@ -1778,7 +1812,12 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
        bnx2i_ep_ofld_list_del(hba, bnx2i_ep);
 
        if (bnx2i_ep->state != EP_STATE_OFLD_COMPL) {
-               rc = -ENOSPC;
+               if (bnx2i_ep->state == EP_STATE_OFLD_FAILED_CID_BUSY) {
+                       printk(KERN_ALERT "bnx2i (%s): iscsi cid %d is busy\n",
+                               hba->netdev->name, bnx2i_ep->ep_iscsi_cid);
+                       rc = -EBUSY;
+               } else
+                       rc = -ENOSPC;
                goto conn_failed;
        }
 
@@ -1786,7 +1825,8 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
                             iscsi_cid, &bnx2i_ep->cm_sk, bnx2i_ep);
        if (rc) {
                rc = -EINVAL;
-               goto conn_failed;
+               /* Need to terminate and cleanup the connection */
+               goto release_ep;
        }
 
        bnx2i_ep->cm_sk->rcv_buf = 256 * 1024;
@@ -1830,15 +1870,12 @@ release_ep:
                return ERR_PTR(rc);
        }
 conn_failed:
-net_if_down:
-iscsi_cid_err:
        bnx2i_free_qp_resc(hba, bnx2i_ep);
 qp_resc_err:
        bnx2i_free_ep(ep);
 check_busy:
        mutex_unlock(&hba->net_dev_lock);
 nohba:
-       bnx2i_unreg_dev_all();
        return ERR_PTR(rc);
 }
 
@@ -1898,12 +1935,13 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
                cnic_dev_10g = 1;
 
        switch (bnx2i_ep->state) {
-       case EP_STATE_CONNECT_START:
+       case EP_STATE_CONNECT_FAILED:
        case EP_STATE_CLEANUP_FAILED:
        case EP_STATE_OFLD_FAILED:
        case EP_STATE_DISCONN_TIMEDOUT:
                ret = 0;
                break;
+       case EP_STATE_CONNECT_START:
        case EP_STATE_CONNECT_COMPL:
        case EP_STATE_ULP_UPDATE_START:
        case EP_STATE_ULP_UPDATE_COMPL:
@@ -1914,13 +1952,10 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
                ret = 1;
                break;
        case EP_STATE_TCP_RST_RCVD:
-               ret = 0;
-               break;
-       case EP_STATE_CONNECT_FAILED:
                if (cnic_dev_10g)
-                       ret = 1;
-               else
                        ret = 0;
+               else
+                       ret = 1;
                break;
        default:
                ret = 0;
@@ -1953,7 +1988,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
        if (!cnic)
                return 0;
 
-       if (bnx2i_ep->state == EP_STATE_IDLE)
+       if (bnx2i_ep->state == EP_STATE_IDLE ||
+           bnx2i_ep->state == EP_STATE_DISCONN_TIMEDOUT)
                return 0;
 
        if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
@@ -1979,9 +2015,10 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
                        if (session->state == ISCSI_STATE_LOGGING_OUT) {
                                if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) {
                                        /* Logout sent, but no resp */
-                                       printk(KERN_ALERT "bnx2i - WARNING "
-                                               "logout response was not "
-                                               "received!\n");
+                                       printk(KERN_ALERT "bnx2i (%s): WARNING"
+                                               " logout response was not "
+                                               "received!\n",
+                                               bnx2i_ep->hba->netdev->name);
                                } else if (bnx2i_ep->state ==
                                           EP_STATE_LOGOUT_RESP_RCVD)
                                        close = 1;
@@ -1999,9 +2036,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
        else
                close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
 
-       /* No longer allow CFC delete if cm_close/abort fails the request */
        if (close_ret)
-               printk(KERN_ALERT "bnx2i: %s close/abort(%d) returned %d\n",
+               printk(KERN_ALERT "bnx2i (%s): close/abort(%d) returned %d\n",
                        bnx2i_ep->hba->netdev->name, close, close_ret);
        else
                /* wait for option-2 conn teardown */
@@ -2015,7 +2051,7 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
 destroy_conn:
        bnx2i_ep_active_list_del(hba, bnx2i_ep);
        if (bnx2i_tear_down_conn(hba, bnx2i_ep))
-               ret = -EINVAL;
+               return -EINVAL;
 out:
        bnx2i_ep->state = EP_STATE_IDLE;
        return ret;
@@ -2054,14 +2090,17 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
 
        mutex_lock(&hba->net_dev_lock);
 
-       if (bnx2i_ep->state == EP_STATE_IDLE)
-               goto return_bnx2i_ep;
+       if (bnx2i_ep->state == EP_STATE_DISCONN_TIMEDOUT)
+               goto out;
 
-       if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state))
+       if (bnx2i_ep->state == EP_STATE_IDLE)
                goto free_resc;
 
-       if (bnx2i_ep->hba_age != hba->age)
+       if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) ||
+           (bnx2i_ep->hba_age != hba->age)) {
+               bnx2i_ep_active_list_del(hba, bnx2i_ep);
                goto free_resc;
+       }
 
        /* Do all chip cleanup here */
        if (bnx2i_hw_ep_disconnect(bnx2i_ep)) {
@@ -2070,14 +2109,13 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
        }
 free_resc:
        bnx2i_free_qp_resc(hba, bnx2i_ep);
-return_bnx2i_ep:
+
        if (bnx2i_conn)
                bnx2i_conn->ep = NULL;
 
        bnx2i_free_ep(ep);
+out:
        mutex_unlock(&hba->net_dev_lock);
-       if (!hba->ofld_conns_active)
-               bnx2i_unreg_dev_all();
 
        wake_up_interruptible(&hba->eh_wait);
 }
index 96426b751eb2e6a3e3359b069ab51759f6095772..9174196d90336cb8430f25e3375fd02b5b56aae9 100644 (file)
@@ -1,12 +1,13 @@
 /* bnx2i_sysfs.c: Broadcom NetXtreme II iSCSI driver.
  *
- * Copyright (c) 2004 - 2009 Broadcom Corporation
+ * Copyright (c) 2004 - 2010 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation.
  *
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
+ * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
  */
 
 #include "bnx2i.h"
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 6fae3d285ae79d5680f3d1e5d4cad02f5b47d3b6..b837c5b3c8f9daf70dfa9031d24ecb418330e4e6 100644 (file)
@@ -442,12 +442,19 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
        sdev = q->queuedata;
        if (sdev && sdev->scsi_dh_data)
                scsi_dh = sdev->scsi_dh_data->scsi_dh;
-       if (!scsi_dh || !get_device(&sdev->sdev_gendev))
+       if (!scsi_dh || !get_device(&sdev->sdev_gendev) ||
+           sdev->sdev_state == SDEV_CANCEL ||
+           sdev->sdev_state == SDEV_DEL)
                err = SCSI_DH_NOSYS;
+       if (sdev->sdev_state == SDEV_OFFLINE)
+               err = SCSI_DH_DEV_OFFLINED;
        spin_unlock_irqrestore(q->queue_lock, flags);
 
-       if (err)
+       if (err) {
+               if (fn)
+                       fn(data, err);
                return err;
+       }
 
        if (scsi_dh->activate)
                err = scsi_dh->activate(sdev, fn, data);
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 d23a538a9dfcca1e5bae286fb8305796dd6a8233..9f9600b6700161231cf815ad030d3a98f0acaae5 100644 (file)
@@ -854,7 +854,6 @@ static void fcoe_if_destroy(struct fc_lport *lport)
 
        /* Cleanup the fc_lport */
        fc_lport_destroy(lport);
-       fc_fcp_destroy(lport);
 
        /* Stop the transmit retry timer */
        del_timer_sync(&port->timer);
@@ -876,6 +875,9 @@ static void fcoe_if_destroy(struct fc_lport *lport)
        fc_remove_host(lport->host);
        scsi_remove_host(lport->host);
 
+       /* Destroy lport scsi_priv */
+       fc_fcp_destroy(lport);
+
        /* There are no more rports or I/O, free the EM */
        fc_exch_mgr_free(lport);
 
index bc17c71232023c7d3b830a541df976de7146a72c..625c6be25396d79bbfffb192d4e1bdb7cbd7aad9 100644 (file)
@@ -54,6 +54,7 @@ MODULE_LICENSE("GPL v2");
 static void fcoe_ctlr_timeout(unsigned long);
 static void fcoe_ctlr_timer_work(struct work_struct *);
 static void fcoe_ctlr_recv_work(struct work_struct *);
+static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *);
 
 static void fcoe_ctlr_vn_start(struct fcoe_ctlr *);
 static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *);
@@ -176,6 +177,7 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode)
        fip->mode = mode;
        INIT_LIST_HEAD(&fip->fcfs);
        mutex_init(&fip->ctlr_mutex);
+       spin_lock_init(&fip->ctlr_lock);
        fip->flogi_oxid = FC_XID_UNKNOWN;
        setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip);
        INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work);
@@ -230,6 +232,49 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
 }
 EXPORT_SYMBOL(fcoe_ctlr_destroy);
 
+/**
+ * fcoe_ctlr_announce() - announce new FCF selection
+ * @fip: The FCoE controller
+ *
+ * Also sets the destination MAC for FCoE and control packets
+ *
+ * Called with neither ctlr_mutex nor ctlr_lock held.
+ */
+static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
+{
+       struct fcoe_fcf *sel;
+       struct fcoe_fcf *fcf;
+
+       mutex_lock(&fip->ctlr_mutex);
+       spin_lock_bh(&fip->ctlr_lock);
+
+       kfree_skb(fip->flogi_req);
+       fip->flogi_req = NULL;
+       list_for_each_entry(fcf, &fip->fcfs, list)
+               fcf->flogi_sent = 0;
+
+       spin_unlock_bh(&fip->ctlr_lock);
+       sel = fip->sel_fcf;
+
+       if (sel && !compare_ether_addr(sel->fcf_mac, fip->dest_addr))
+               goto unlock;
+       if (!is_zero_ether_addr(fip->dest_addr)) {
+               printk(KERN_NOTICE "libfcoe: host%d: "
+                      "FIP Fibre-Channel Forwarder MAC %pM deselected\n",
+                      fip->lp->host->host_no, fip->dest_addr);
+               memset(fip->dest_addr, 0, ETH_ALEN);
+       }
+       if (sel) {
+               printk(KERN_INFO "libfcoe: host%d: FIP selected "
+                      "Fibre-Channel Forwarder MAC %pM\n",
+                      fip->lp->host->host_no, sel->fcf_mac);
+               memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
+               fip->map_dest = 0;
+       }
+unlock:
+       mutex_unlock(&fip->ctlr_mutex);
+}
+
 /**
  * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port
  * @fip: The FCoE controller to get the maximum FCoE size from
@@ -564,6 +609,9 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
  * The caller must check that the length is a multiple of 4.
  * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
  * The the skb must also be an fc_frame.
+ *
+ * This is called from the lower-level driver with spinlocks held,
+ * so we must not take a mutex here.
  */
 int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
                       struct sk_buff *skb)
@@ -601,7 +649,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
        switch (op) {
        case ELS_FLOGI:
                op = FIP_DT_FLOGI;
-               break;
+               if (fip->mode == FIP_MODE_VN2VN)
+                       break;
+               spin_lock_bh(&fip->ctlr_lock);
+               kfree_skb(fip->flogi_req);
+               fip->flogi_req = skb;
+               fip->flogi_req_send = 1;
+               spin_unlock_bh(&fip->ctlr_lock);
+               schedule_work(&fip->timer_work);
+               return -EINPROGRESS;
        case ELS_FDISC:
                if (ntoh24(fh->fh_s_id))
                        return 0;
@@ -922,11 +978,9 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
        }
        mtu_valid = fcoe_ctlr_mtu_valid(fcf);
        fcf->time = jiffies;
-       if (!found) {
-               LIBFCOE_FIP_DBG(fip, "New FCF for fab %16.16llx "
-                               "map %x val %d\n",
-                               fcf->fabric_name, fcf->fc_map, mtu_valid);
-       }
+       if (!found)
+               LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n",
+                               fcf->fabric_name, fcf->fcf_mac);
 
        /*
         * If this advertisement is not solicited and our max receive size
@@ -944,6 +998,17 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
        if (first && time_after(jiffies, fip->sol_time + sol_tov))
                fcoe_ctlr_solicit(fip, NULL);
 
+       /*
+        * Put this FCF at the head of the list for priority among equals.
+        * This helps in the case of an NPV switch which insists we use
+        * the FCF that answers multicast solicitations, not the others that
+        * are sending periodic multicast advertisements.
+        */
+       if (mtu_valid) {
+               list_del(&fcf->list);
+               list_add(&fcf->list, &fip->fcfs);
+       }
+
        /*
         * If this is the first validated FCF, note the time and
         * set a timer to trigger selection.
@@ -1061,18 +1126,24 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
        els_op = *(u8 *)(fh + 1);
 
        if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) &&
-           sub == FIP_SC_REP && els_op == ELS_LS_ACC &&
-           fip->mode != FIP_MODE_VN2VN) {
-               if (!is_valid_ether_addr(granted_mac)) {
-                       LIBFCOE_FIP_DBG(fip,
-                               "Invalid MAC address %pM in FIP ELS\n",
-                               granted_mac);
-                       goto drop;
-               }
-               memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
+           sub == FIP_SC_REP && fip->mode != FIP_MODE_VN2VN) {
+               if (els_op == ELS_LS_ACC) {
+                       if (!is_valid_ether_addr(granted_mac)) {
+                               LIBFCOE_FIP_DBG(fip,
+                                       "Invalid MAC address %pM in FIP ELS\n",
+                                       granted_mac);
+                               goto drop;
+                       }
+                       memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
 
-               if (fip->flogi_oxid == ntohs(fh->fh_ox_id))
-                       fip->flogi_oxid = FC_XID_UNKNOWN;
+                       if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) {
+                               fip->flogi_oxid = FC_XID_UNKNOWN;
+                               if (els_dtype == FIP_DT_FLOGI)
+                                       fcoe_ctlr_announce(fip);
+                       }
+               } else if (els_dtype == FIP_DT_FLOGI &&
+                          !fcoe_ctlr_flogi_retry(fip))
+                       goto drop;      /* retrying FLOGI so drop reject */
        }
 
        if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) &&
@@ -1326,20 +1397,39 @@ drop:
  * fcoe_ctlr_select() - Select the best FCF (if possible)
  * @fip: The FCoE controller
  *
+ * Returns the selected FCF, or NULL if none are usable.
+ *
  * If there are conflicting advertisements, no FCF can be chosen.
  *
+ * If there is already a selected FCF, this will choose a better one or
+ * an equivalent one that hasn't already been sent a FLOGI.
+ *
  * Called with lock held.
  */
-static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
+static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
 {
        struct fcoe_fcf *fcf;
-       struct fcoe_fcf *best = NULL;
+       struct fcoe_fcf *best = fip->sel_fcf;
+       struct fcoe_fcf *first;
+
+       first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list);
 
        list_for_each_entry(fcf, &fip->fcfs, list) {
-               LIBFCOE_FIP_DBG(fip, "consider FCF for fab %16.16llx "
-                               "VFID %d map %x val %d\n",
-                               fcf->fabric_name, fcf->vfid,
-                               fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
+               LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx "
+                               "VFID %d mac %pM map %x val %d "
+                               "sent %u pri %u\n",
+                               fcf->fabric_name, fcf->vfid, fcf->fcf_mac,
+                               fcf->fc_map, fcoe_ctlr_mtu_valid(fcf),
+                               fcf->flogi_sent, fcf->pri);
+               if (fcf->fabric_name != first->fabric_name ||
+                   fcf->vfid != first->vfid ||
+                   fcf->fc_map != first->fc_map) {
+                       LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
+                                       "or FC-MAP\n");
+                       return NULL;
+               }
+               if (fcf->flogi_sent)
+                       continue;
                if (!fcoe_ctlr_fcf_usable(fcf)) {
                        LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx "
                                        "map %x %svalid %savailable\n",
@@ -1349,21 +1439,131 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
                                        "" : "un");
                        continue;
                }
-               if (!best) {
-                       best = fcf;
-                       continue;
-               }
-               if (fcf->fabric_name != best->fabric_name ||
-                   fcf->vfid != best->vfid ||
-                   fcf->fc_map != best->fc_map) {
-                       LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
-                                       "or FC-MAP\n");
-                       return;
-               }
-               if (fcf->pri < best->pri)
+               if (!best || fcf->pri < best->pri || best->flogi_sent)
                        best = fcf;
        }
        fip->sel_fcf = best;
+       if (best) {
+               LIBFCOE_FIP_DBG(fip, "using FCF mac %pM\n", best->fcf_mac);
+               fip->port_ka_time = jiffies +
+                       msecs_to_jiffies(FIP_VN_KA_PERIOD);
+               fip->ctlr_ka_time = jiffies + best->fka_period;
+               if (time_before(fip->ctlr_ka_time, fip->timer.expires))
+                       mod_timer(&fip->timer, fip->ctlr_ka_time);
+       }
+       return best;
+}
+
+/**
+ * fcoe_ctlr_flogi_send_locked() - send FIP-encapsulated FLOGI to current FCF
+ * @fip: The FCoE controller
+ *
+ * Returns non-zero error if it could not be sent.
+ *
+ * Called with ctlr_mutex and ctlr_lock held.
+ * Caller must verify that fip->sel_fcf is not NULL.
+ */
+static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip)
+{
+       struct sk_buff *skb;
+       struct sk_buff *skb_orig;
+       struct fc_frame_header *fh;
+       int error;
+
+       skb_orig = fip->flogi_req;
+       if (!skb_orig)
+               return -EINVAL;
+
+       /*
+        * Clone and send the FLOGI request.  If clone fails, use original.
+        */
+       skb = skb_clone(skb_orig, GFP_ATOMIC);
+       if (!skb) {
+               skb = skb_orig;
+               fip->flogi_req = NULL;
+       }
+       fh = (struct fc_frame_header *)skb->data;
+       error = fcoe_ctlr_encaps(fip, fip->lp, FIP_DT_FLOGI, skb,
+                                ntoh24(fh->fh_d_id));
+       if (error) {
+               kfree_skb(skb);
+               return error;
+       }
+       fip->send(fip, skb);
+       fip->sel_fcf->flogi_sent = 1;
+       return 0;
+}
+
+/**
+ * fcoe_ctlr_flogi_retry() - resend FLOGI request to a new FCF if possible
+ * @fip: The FCoE controller
+ *
+ * Returns non-zero error code if there's no FLOGI request to retry or
+ * no alternate FCF available.
+ */
+static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
+{
+       struct fcoe_fcf *fcf;
+       int error;
+
+       mutex_lock(&fip->ctlr_mutex);
+       spin_lock_bh(&fip->ctlr_lock);
+       LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n");
+       fcf = fcoe_ctlr_select(fip);
+       if (!fcf || fcf->flogi_sent) {
+               kfree_skb(fip->flogi_req);
+               fip->flogi_req = NULL;
+               error = -ENOENT;
+       } else {
+               fcoe_ctlr_solicit(fip, NULL);
+               error = fcoe_ctlr_flogi_send_locked(fip);
+       }
+       spin_unlock_bh(&fip->ctlr_lock);
+       mutex_unlock(&fip->ctlr_mutex);
+       return error;
+}
+
+
+/**
+ * fcoe_ctlr_flogi_send() - Handle sending of FIP FLOGI.
+ * @fip: The FCoE controller that timed out
+ *
+ * Done here because fcoe_ctlr_els_send() can't get mutex.
+ *
+ * Called with ctlr_mutex held.  The caller must not hold ctlr_lock.
+ */
+static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
+{
+       struct fcoe_fcf *fcf;
+
+       spin_lock_bh(&fip->ctlr_lock);
+       fcf = fip->sel_fcf;
+       if (!fcf || !fip->flogi_req_send)
+               goto unlock;
+
+       LIBFCOE_FIP_DBG(fip, "sending FLOGI\n");
+
+       /*
+        * If this FLOGI is being sent due to a timeout retry
+        * to the same FCF as before, select a different FCF if possible.
+        */
+       if (fcf->flogi_sent) {
+               LIBFCOE_FIP_DBG(fip, "sending FLOGI - reselect\n");
+               fcf = fcoe_ctlr_select(fip);
+               if (!fcf || fcf->flogi_sent) {
+                       LIBFCOE_FIP_DBG(fip, "sending FLOGI - clearing\n");
+                       list_for_each_entry(fcf, &fip->fcfs, list)
+                               fcf->flogi_sent = 0;
+                       fcf = fcoe_ctlr_select(fip);
+               }
+       }
+       if (fcf) {
+               fcoe_ctlr_flogi_send_locked(fip);
+               fip->flogi_req_send = 0;
+       } else /* XXX */
+               LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n");
+unlock:
+       spin_unlock_bh(&fip->ctlr_lock);
 }
 
 /**
@@ -1411,34 +1611,16 @@ static void fcoe_ctlr_timer_work(struct work_struct *work)
        sel = fip->sel_fcf;
        if (!sel && fip->sel_time) {
                if (time_after_eq(jiffies, fip->sel_time)) {
-                       fcoe_ctlr_select(fip);
-                       sel = fip->sel_fcf;
+                       sel = fcoe_ctlr_select(fip);
                        fip->sel_time = 0;
                } else if (time_after(next_timer, fip->sel_time))
                        next_timer = fip->sel_time;
        }
 
-       if (sel != fcf) {
-               fcf = sel;              /* the old FCF may have been freed */
-               if (sel) {
-                       printk(KERN_INFO "libfcoe: host%d: FIP selected "
-                              "Fibre-Channel Forwarder MAC %pM\n",
-                              fip->lp->host->host_no, sel->fcf_mac);
-                       memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
-                       fip->map_dest = 0;
-                       fip->port_ka_time = jiffies +
-                               msecs_to_jiffies(FIP_VN_KA_PERIOD);
-                       fip->ctlr_ka_time = jiffies + sel->fka_period;
-                       if (time_after(next_timer, fip->ctlr_ka_time))
-                               next_timer = fip->ctlr_ka_time;
-               } else {
-                       printk(KERN_NOTICE "libfcoe: host%d: "
-                              "FIP Fibre-Channel Forwarder timed out.  "
-                              "Starting FCF discovery.\n",
-                              fip->lp->host->host_no);
-                       reset = 1;
-               }
-       }
+       if (sel && fip->flogi_req_send)
+               fcoe_ctlr_flogi_send(fip);
+       else if (!sel && fcf)
+               reset = 1;
 
        if (sel && !sel->fd_flags) {
                if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
@@ -2475,7 +2657,7 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip)
        case FIP_ST_LINK_WAIT:
                goto unlock;
        default:
-               WARN(1, "unexpected state %d", fip->state);
+               WARN(1, "unexpected state %d\n", fip->state);
                goto unlock;
        }
        mod_timer(&fip->timer, next_time);
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..12deffccb8da2f13358202c229c530726edd9227 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>
@@ -91,11 +90,7 @@ static const struct pci_device_id hpsa_pci_device_id[] = {
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3252},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3253},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3254},
-#define PCI_DEVICE_ID_HP_CISSF 0x333f
-       {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x333F},
-       {PCI_VENDOR_ID_HP,     PCI_ANY_ID,             PCI_ANY_ID, PCI_ANY_ID,
-               PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
-       {PCI_VENDOR_ID_COMPAQ,     PCI_ANY_ID,             PCI_ANY_ID, PCI_ANY_ID,
+       {PCI_VENDOR_ID_HP,     PCI_ANY_ID,      PCI_ANY_ID, PCI_ANY_ID,
                PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
        {0,}
 };
@@ -114,8 +109,6 @@ static struct board_type products[] = {
        {0x3249103C, "Smart Array P812", &SA5_access},
        {0x324a103C, "Smart Array P712m", &SA5_access},
        {0x324b103C, "Smart Array P711m", &SA5_access},
-       {0x3233103C, "StorageWorks P1210m", &SA5_access},
-       {0x333F103C, "StorageWorks P1210m", &SA5_access},
        {0x3250103C, "Smart Array", &SA5_access},
        {0x3250113C, "Smart Array", &SA5_access},
        {0x3250123C, "Smart Array", &SA5_access},
@@ -143,8 +136,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);
@@ -649,11 +641,6 @@ static void fixup_botched_add(struct ctlr_info *h,
 static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1,
        struct hpsa_scsi_dev_t *dev2)
 {
-       if ((is_logical_dev_addr_mode(dev1->scsi3addr) ||
-               (dev1->lun != -1 && dev2->lun != -1)) &&
-               dev1->devtype != 0x0C)
-               return (memcmp(dev1, dev2, sizeof(*dev1)) == 0);
-
        /* we compare everything except lun and target as these
         * are not yet assigned.  Compare parts likely
         * to differ first
@@ -668,12 +655,8 @@ static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1,
                return 0;
        if (memcmp(dev1->vendor, dev2->vendor, sizeof(dev1->vendor)) != 0)
                return 0;
-       if (memcmp(dev1->revision, dev2->revision, sizeof(dev1->revision)) != 0)
-               return 0;
        if (dev1->devtype != dev2->devtype)
                return 0;
-       if (dev1->raid_level != dev2->raid_level)
-               return 0;
        if (dev1->bus != dev2->bus)
                return 0;
        return 1;
@@ -1485,8 +1468,6 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                sizeof(this_device->vendor));
        memcpy(this_device->model, &inq_buff[16],
                sizeof(this_device->model));
-       memcpy(this_device->revision, &inq_buff[32],
-               sizeof(this_device->revision));
        memset(this_device->device_id, 0,
                sizeof(this_device->device_id));
        hpsa_get_device_id(h, scsi3addr, this_device->device_id,
@@ -1926,7 +1907,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 +2001,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 a203ef65cb504e1d03b023e9500b239a0ea09db9..19586e189f0f120a67c0494330d499ef54ff08e7 100644 (file)
@@ -45,7 +45,6 @@ struct hpsa_scsi_dev_t {
        unsigned char device_id[16];    /* from inquiry pg. 0x83 */
        unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
        unsigned char model[16];        /* bytes 16-31 of inquiry data */
-       unsigned char revision[4];      /* bytes 32-35 of inquiry data */
        unsigned char raid_level;       /* from inquiry page 0xC1 */
 };
 
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..b7650613b8c2606caef87d83a6b0e2a74cc7ca09 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
@@ -2491,23 +2493,23 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport)
 }
 
 static const struct ibmvfc_async_desc ae_desc [] = {
-       { IBMVFC_AE_ELS_PLOGI,          "PLOGI",                IBMVFC_DEFAULT_LOG_LEVEL + 1 },
-       { IBMVFC_AE_ELS_LOGO,           "LOGO",         IBMVFC_DEFAULT_LOG_LEVEL + 1 },
-       { IBMVFC_AE_ELS_PRLO,           "PRLO",         IBMVFC_DEFAULT_LOG_LEVEL + 1 },
-       { IBMVFC_AE_SCN_NPORT,          "N-Port SCN",   IBMVFC_DEFAULT_LOG_LEVEL + 1 },
-       { IBMVFC_AE_SCN_GROUP,          "Group SCN",    IBMVFC_DEFAULT_LOG_LEVEL + 1 },
-       { IBMVFC_AE_SCN_DOMAIN,         "Domain SCN",   IBMVFC_DEFAULT_LOG_LEVEL },
-       { IBMVFC_AE_SCN_FABRIC,         "Fabric SCN",   IBMVFC_DEFAULT_LOG_LEVEL },
-       { IBMVFC_AE_LINK_UP,            "Link Up",              IBMVFC_DEFAULT_LOG_LEVEL },
-       { IBMVFC_AE_LINK_DOWN,          "Link Down",    IBMVFC_DEFAULT_LOG_LEVEL },
-       { IBMVFC_AE_LINK_DEAD,          "Link Dead",    IBMVFC_DEFAULT_LOG_LEVEL },
-       { IBMVFC_AE_HALT,                       "Halt",         IBMVFC_DEFAULT_LOG_LEVEL },
-       { IBMVFC_AE_RESUME,             "Resume",               IBMVFC_DEFAULT_LOG_LEVEL },
-       { IBMVFC_AE_ADAPTER_FAILED,     "Adapter Failed",       IBMVFC_DEFAULT_LOG_LEVEL },
+       { "PLOGI",      IBMVFC_AE_ELS_PLOGI,    IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+       { "LOGO",       IBMVFC_AE_ELS_LOGO,     IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+       { "PRLO",       IBMVFC_AE_ELS_PRLO,     IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+       { "N-Port SCN", IBMVFC_AE_SCN_NPORT,    IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+       { "Group SCN",  IBMVFC_AE_SCN_GROUP,    IBMVFC_DEFAULT_LOG_LEVEL + 1 },
+       { "Domain SCN", IBMVFC_AE_SCN_DOMAIN,   IBMVFC_DEFAULT_LOG_LEVEL },
+       { "Fabric SCN", IBMVFC_AE_SCN_FABRIC,   IBMVFC_DEFAULT_LOG_LEVEL },
+       { "Link Up",    IBMVFC_AE_LINK_UP,      IBMVFC_DEFAULT_LOG_LEVEL },
+       { "Link Down",  IBMVFC_AE_LINK_DOWN,    IBMVFC_DEFAULT_LOG_LEVEL },
+       { "Link Dead",  IBMVFC_AE_LINK_DEAD,    IBMVFC_DEFAULT_LOG_LEVEL },
+       { "Halt",       IBMVFC_AE_HALT,         IBMVFC_DEFAULT_LOG_LEVEL },
+       { "Resume",     IBMVFC_AE_RESUME,       IBMVFC_DEFAULT_LOG_LEVEL },
+       { "Adapter Failed", IBMVFC_AE_ADAPTER_FAILED, IBMVFC_DEFAULT_LOG_LEVEL },
 };
 
 static const struct ibmvfc_async_desc unknown_ae = {
-       0, "Unknown async", IBMVFC_DEFAULT_LOG_LEVEL
+       "Unknown async", 0, IBMVFC_DEFAULT_LOG_LEVEL
 };
 
 /**
index ef663e7c9bbcf53dbb7c16f021d51d2091a406af..834c37fc7ce9be5dcb73825d4b3f50da8beae800 100644 (file)
@@ -542,8 +542,8 @@ enum ibmvfc_async_event {
 };
 
 struct ibmvfc_async_desc {
-       enum ibmvfc_async_event ae;
        const char *desc;
+       enum ibmvfc_async_event ae;
        int log_level;
 };
 
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..de2e09e49a3eefaa23d120a413758c36f913dcad 100644 (file)
@@ -146,7 +146,7 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
                }
        },
        { /* CRoC */
-               .mailbox = 0x00040,
+               .mailbox = 0x00044,
                .cache_line_size = 0x20,
                {
                        .set_interrupt_mask_reg = 0x00010,
@@ -1048,6 +1048,8 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res,
                        sizeof(res->res_path));
 
                res->bus = 0;
+               memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
+                       sizeof(res->dev_lun.scsi_lun));
                res->lun = scsilun_to_int(&res->dev_lun);
 
                if (res->type == IPR_RES_TYPE_GENERIC_SCSI) {
@@ -1063,9 +1065,6 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res,
                                                                  ioa_cfg->max_devs_supported);
                                set_bit(res->target, ioa_cfg->target_ids);
                        }
-
-                       memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
-                               sizeof(res->dev_lun.scsi_lun));
                } else if (res->type == IPR_RES_TYPE_IOAFP) {
                        res->bus = IPR_IOAFP_VIRTUAL_BUS;
                        res->target = 0;
@@ -1116,7 +1115,7 @@ static int ipr_is_same_device(struct ipr_resource_entry *res,
        if (res->ioa_cfg->sis64) {
                if (!memcmp(&res->dev_id, &cfgtew->u.cfgte64->dev_id,
                                        sizeof(cfgtew->u.cfgte64->dev_id)) &&
-                       !memcmp(&res->lun, &cfgtew->u.cfgte64->lun,
+                       !memcmp(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
                                        sizeof(cfgtew->u.cfgte64->lun))) {
                        return 1;
                }
@@ -2901,6 +2900,12 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
                return;
        }
 
+       if (ioa_cfg->sis64) {
+               spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+               ssleep(IPR_DUMP_DELAY_SECONDS);
+               spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+       }
+
        start_addr = readl(ioa_cfg->ioa_mailbox);
 
        if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) {
@@ -5709,7 +5714,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 +5797,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
@@ -7470,6 +7477,29 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
        list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q);
 }
 
+/**
+ * ipr_reset_get_unit_check_job - Call to get the unit check buffer.
+ * @ipr_cmd:   ipr command struct
+ *
+ * Description: This function will call to get the unit check buffer.
+ *
+ * Return value:
+ *     IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_get_unit_check_job(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
+       ENTER;
+       ioa_cfg->ioa_unit_checked = 0;
+       ipr_get_unit_check_buffer(ioa_cfg);
+       ipr_cmd->job_step = ipr_reset_alert;
+       ipr_reset_start_timer(ipr_cmd, 0);
+
+       LEAVE;
+       return IPR_RC_JOB_RETURN;
+}
+
 /**
  * ipr_reset_restore_cfg_space - Restore PCI config space.
  * @ipr_cmd:   ipr command struct
@@ -7510,11 +7540,17 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
        }
 
        if (ioa_cfg->ioa_unit_checked) {
-               ioa_cfg->ioa_unit_checked = 0;
-               ipr_get_unit_check_buffer(ioa_cfg);
-               ipr_cmd->job_step = ipr_reset_alert;
-               ipr_reset_start_timer(ipr_cmd, 0);
-               return IPR_RC_JOB_RETURN;
+               if (ioa_cfg->sis64) {
+                       ipr_cmd->job_step = ipr_reset_get_unit_check_job;
+                       ipr_reset_start_timer(ipr_cmd, IPR_DUMP_DELAY_TIMEOUT);
+                       return IPR_RC_JOB_RETURN;
+               } else {
+                       ioa_cfg->ioa_unit_checked = 0;
+                       ipr_get_unit_check_buffer(ioa_cfg);
+                       ipr_cmd->job_step = ipr_reset_alert;
+                       ipr_reset_start_timer(ipr_cmd, 0);
+                       return IPR_RC_JOB_RETURN;
+               }
        }
 
        if (ioa_cfg->in_ioa_bringdown) {
index b28a00f1082c3e3bbab4e412725030626890652c..13f425fb8851f5206f74be7a3c0615dea0b0ca8d 100644 (file)
 #define IPR_WAIT_FOR_BIST_TIMEOUT              (2 * HZ)
 #define IPR_PCI_RESET_TIMEOUT                  (HZ / 2)
 #define IPR_DUMP_TIMEOUT                       (15 * HZ)
+#define IPR_DUMP_DELAY_SECONDS                 4
+#define IPR_DUMP_DELAY_TIMEOUT                 (IPR_DUMP_DELAY_SECONDS * HZ)
 
 /*
  * SCSI Literals
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 ec2a1aec2350279bdd0b177b321f5694ff9a948b..d21367d3305fd6de6bd68f0505618ff97b6b927b 100644 (file)
@@ -67,6 +67,11 @@ struct workqueue_struct *fc_exch_workqueue;
 struct fc_exch_pool {
        u16              next_index;
        u16              total_exches;
+
+       /* two cache of free slot in exch array */
+       u16              left;
+       u16              right;
+
        spinlock_t       lock;
        struct list_head ex_list;
 };
@@ -108,7 +113,6 @@ struct fc_exch_mgr {
                atomic_t non_bls_resp;
        } stats;
 };
-#define        fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
 
 /**
  * struct fc_exch_mgr_anchor - primary structure for list of EMs
@@ -397,13 +401,23 @@ static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
 static void fc_exch_delete(struct fc_exch *ep)
 {
        struct fc_exch_pool *pool;
+       u16 index;
 
        pool = ep->pool;
        spin_lock_bh(&pool->lock);
        WARN_ON(pool->total_exches <= 0);
        pool->total_exches--;
-       fc_exch_ptr_set(pool, (ep->xid - ep->em->min_xid) >> fc_cpu_order,
-                       NULL);
+
+       /* update cache of free slot */
+       index = (ep->xid - ep->em->min_xid) >> fc_cpu_order;
+       if (pool->left == FC_XID_UNKNOWN)
+               pool->left = index;
+       else if (pool->right == FC_XID_UNKNOWN)
+               pool->right = index;
+       else
+               pool->next_index = index;
+
+       fc_exch_ptr_set(pool, index, NULL);
        list_del(&ep->ex_list);
        spin_unlock_bh(&pool->lock);
        fc_exch_release(ep);    /* drop hold for exch in mp */
@@ -636,10 +650,13 @@ static void fc_exch_timeout(struct work_struct *work)
                if (e_stat & ESB_ST_ABNORMAL)
                        rc = fc_exch_done_locked(ep);
                spin_unlock_bh(&ep->ex_lock);
-               if (!rc)
-                       fc_exch_delete(ep);
                if (resp)
                        resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg);
+               if (!rc) {
+                       /* delete the exchange if it's already being aborted */
+                       fc_exch_delete(ep);
+                       return;
+               }
                fc_seq_exch_abort(sp, 2 * ep->r_a_tov);
                goto done;
        }
@@ -679,6 +696,19 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
        pool = per_cpu_ptr(mp->pool, cpu);
        spin_lock_bh(&pool->lock);
        put_cpu();
+
+       /* peek cache of free slot */
+       if (pool->left != FC_XID_UNKNOWN) {
+               index = pool->left;
+               pool->left = FC_XID_UNKNOWN;
+               goto hit;
+       }
+       if (pool->right != FC_XID_UNKNOWN) {
+               index = pool->right;
+               pool->right = FC_XID_UNKNOWN;
+               goto hit;
+       }
+
        index = pool->next_index;
        /* allocate new exch from pool */
        while (fc_exch_ptr_get(pool, index)) {
@@ -687,7 +717,7 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
                        goto err;
        }
        pool->next_index = index == mp->pool_max_index ? 0 : index + 1;
-
+hit:
        fc_exch_hold(ep);       /* hold for exch in mp */
        spin_lock_init(&ep->ex_lock);
        /*
@@ -1247,7 +1277,7 @@ static struct fc_seq *fc_seq_assign(struct fc_lport *lport, struct fc_frame *fp)
 
        list_for_each_entry(ema, &lport->ema_list, ema_list)
                if ((!ema->match || ema->match(fp)) &&
-                   fc_seq_lookup_recip(lport, ema->mp, fp) != FC_RJT_NONE)
+                   fc_seq_lookup_recip(lport, ema->mp, fp) == FC_RJT_NONE)
                        break;
        return fr_seq(fp);
 }
@@ -1343,7 +1373,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
        }
        if (ep->esb_stat & ESB_ST_COMPLETE) {
                atomic_inc(&mp->stats.xid_not_found);
-               goto out;
+               goto rel;
        }
        if (ep->rxid == FC_XID_UNKNOWN)
                ep->rxid = ntohs(fh->fh_rx_id);
@@ -2181,6 +2211,8 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
                goto free_mempool;
        for_each_possible_cpu(cpu) {
                pool = per_cpu_ptr(mp->pool, cpu);
+               pool->left = FC_XID_UNKNOWN;
+               pool->right = FC_XID_UNKNOWN;
                spin_lock_init(&pool->lock);
                INIT_LIST_HEAD(&pool->ex_list);
        }
index e340373b509b6528ea0602d410eb902c3b233321..cdc06cda76e53bbf1252d79702cf0e94613e10b9 100644 (file)
@@ -57,6 +57,9 @@ struct kmem_cache *scsi_pkt_cachep;
 #define FC_SRB_READ            (1 << 1)
 #define FC_SRB_WRITE           (1 << 0)
 
+/* constant added to e_d_tov timeout to get rec_tov value */
+#define REC_TOV_CONST          1
+
 /*
  * The SCp.ptr should be tested and set under the scsi_pkt_queue lock
  */
@@ -96,7 +99,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *);
 static void fc_fcp_complete_locked(struct fc_fcp_pkt *);
 static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *);
 static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *);
-static void fc_fcp_recovery(struct fc_fcp_pkt *);
+static void fc_fcp_recovery(struct fc_fcp_pkt *, u8 code);
 static void fc_fcp_timeout(unsigned long);
 static void fc_fcp_rec(struct fc_fcp_pkt *);
 static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *);
@@ -120,14 +123,13 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *, struct fc_frame *);
 #define FC_DATA_UNDRUN         7
 #define FC_ERROR               8
 #define FC_HRD_ERROR           9
-#define FC_CMD_RECOVERY                10
+#define FC_CRC_ERROR           10
+#define FC_TIMED_OUT           11
 
 /*
  * Error recovery timeout values.
  */
-#define FC_SCSI_ER_TIMEOUT     (10 * HZ)
 #define FC_SCSI_TM_TOV         (10 * HZ)
-#define FC_SCSI_REC_TOV                (2 * HZ)
 #define FC_HOST_RESET_TIMEOUT  (30 * HZ)
 #define FC_CAN_QUEUE_PERIOD    (60 * HZ)
 
@@ -438,6 +440,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
        void *buf;
        struct scatterlist *sg;
        u32 nents;
+       u8 host_bcode = FC_COMPLETE;
 
        fh = fc_frame_header_get(fp);
        offset = ntohl(fh->fh_parm_offset);
@@ -446,13 +449,16 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
        buf = fc_frame_payload_get(fp, 0);
 
        /*
-        * if this I/O is ddped then clear it
-        * and initiate recovery since data
-        * frames are expected to be placed
-        * directly in that case.
+        * if this I/O is ddped then clear it and initiate recovery since data
+        * frames are expected to be placed directly in that case.
+        *
+        * Indicate error to scsi-ml because something went wrong with the
+        * ddp handling to get us here.
         */
        if (fsp->xfer_ddp != FC_XID_UNKNOWN) {
                fc_fcp_ddp_done(fsp);
+               FC_FCP_DBG(fsp, "DDP I/O in fc_fcp_recv_data set ERROR\n");
+               host_bcode = FC_ERROR;
                goto err;
        }
        if (offset + len > fsp->data_len) {
@@ -462,6 +468,9 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
                        goto crc_err;
                FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx "
                           "data_len %x\n", len, offset, fsp->data_len);
+
+               /* Data is corrupted indicate scsi-ml should retry */
+               host_bcode = FC_DATA_OVRRUN;
                goto err;
        }
        if (offset != fsp->xfer_len)
@@ -498,8 +507,10 @@ crc_err:
                         * If so, we need to retry the entire operation.
                         * Otherwise, ignore it.
                         */
-                       if (fsp->state & FC_SRB_DISCONTIG)
+                       if (fsp->state & FC_SRB_DISCONTIG) {
+                               host_bcode = FC_CRC_ERROR;
                                goto err;
+                       }
                        return;
                }
        }
@@ -517,7 +528,7 @@ crc_err:
                fc_fcp_complete_locked(fsp);
        return;
 err:
-       fc_fcp_recovery(fsp);
+       fc_fcp_recovery(fsp, host_bcode);
 }
 
 /**
@@ -962,7 +973,13 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
                }
                lport->tt.exch_done(seq);
        }
-       fc_io_compl(fsp);
+       /*
+        * Some resets driven by SCSI are not I/Os and do not have
+        * SCSI commands associated with the requests. We should not
+        * call I/O completion if we do not have a SCSI command.
+        */
+       if (fsp->cmd)
+               fc_io_compl(fsp);
 }
 
 /**
@@ -1072,6 +1089,21 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
        return rc;
 }
 
+/**
+ * get_fsp_rec_tov() - Helper function to get REC_TOV
+ * @fsp: the FCP packet
+ */
+static inline unsigned int get_fsp_rec_tov(struct fc_fcp_pkt *fsp)
+{
+       struct fc_rport *rport;
+       struct fc_rport_libfc_priv *rpriv;
+
+       rport = fsp->rport;
+       rpriv = rport->dd_data;
+
+       return rpriv->e_d_tov + REC_TOV_CONST;
+}
+
 /**
  * fc_fcp_cmd_send() - Send a FCP command
  * @lport: The local port to send the command on
@@ -1089,6 +1121,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
        struct fc_rport_libfc_priv *rpriv;
        const size_t len = sizeof(fsp->cdb_cmd);
        int rc = 0;
+       unsigned int rec_tov;
 
        if (fc_fcp_lock_pkt(fsp))
                return 0;
@@ -1119,10 +1152,13 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
        fsp->seq_ptr = seq;
        fc_fcp_pkt_hold(fsp);   /* hold for fc_fcp_pkt_destroy */
 
+       rec_tov = get_fsp_rec_tov(fsp);
+
        setup_timer(&fsp->timer, fc_fcp_timeout, (unsigned long)fsp);
-       fc_fcp_timer_set(fsp,
-                        (fsp->tgt_flags & FC_RP_FLAGS_REC_SUPPORTED) ?
-                        FC_SCSI_REC_TOV : FC_SCSI_ER_TIMEOUT);
+
+       if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
+               fc_fcp_timer_set(fsp, rec_tov);
+
 unlock:
        fc_fcp_unlock_pkt(fsp);
        return rc;
@@ -1197,13 +1233,16 @@ static void fc_lun_reset_send(unsigned long data)
 {
        struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data;
        struct fc_lport *lport = fsp->lp;
+       unsigned int rec_tov;
+
        if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) {
                if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY)
                        return;
                if (fc_fcp_lock_pkt(fsp))
                        return;
+               rec_tov = get_fsp_rec_tov(fsp);
                setup_timer(&fsp->timer, fc_lun_reset_send, (unsigned long)fsp);
-               fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+               fc_fcp_timer_set(fsp, rec_tov);
                fc_fcp_unlock_pkt(fsp);
        }
 }
@@ -1282,27 +1321,27 @@ static void fc_tm_done(struct fc_seq *seq, struct fc_frame *fp, void *arg)
                 *
                 * scsi-eh will escalate for when either happens.
                 */
-               return;
+               goto out;
        }
 
        if (fc_fcp_lock_pkt(fsp))
-               return;
+               goto out;
 
        /*
         * raced with eh timeout handler.
         */
-       if (!fsp->seq_ptr || !fsp->wait_for_comp) {
-               spin_unlock_bh(&fsp->scsi_pkt_lock);
-               return;
-       }
+       if (!fsp->seq_ptr || !fsp->wait_for_comp)
+               goto out_unlock;
 
        fh = fc_frame_header_get(fp);
        if (fh->fh_type != FC_TYPE_BLS)
                fc_fcp_resp(fsp, fp);
        fsp->seq_ptr = NULL;
        fsp->lp->tt.exch_done(seq);
-       fc_frame_free(fp);
+out_unlock:
        fc_fcp_unlock_pkt(fsp);
+out:
+       fc_frame_free(fp);
 }
 
 /**
@@ -1341,13 +1380,10 @@ static void fc_fcp_timeout(unsigned long data)
 
        if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
                fc_fcp_rec(fsp);
-       else if (time_after_eq(fsp->last_pkt_time + (FC_SCSI_ER_TIMEOUT / 2),
-                              jiffies))
-               fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT);
        else if (fsp->state & FC_SRB_RCV_STATUS)
                fc_fcp_complete_locked(fsp);
        else
-               fc_fcp_recovery(fsp);
+               fc_fcp_recovery(fsp, FC_TIMED_OUT);
        fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
 unlock:
        fc_fcp_unlock_pkt(fsp);
@@ -1373,6 +1409,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
                fc_fcp_complete_locked(fsp);
                return;
        }
+
        fp = fc_fcp_frame_alloc(lport, sizeof(struct fc_els_rec));
        if (!fp)
                goto retry;
@@ -1383,15 +1420,15 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
                       FC_FCTL_REQ, 0);
        if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC,
                                 fc_fcp_rec_resp, fsp,
-                                jiffies_to_msecs(FC_SCSI_REC_TOV))) {
+                                2 * lport->r_a_tov)) {
                fc_fcp_pkt_hold(fsp);           /* hold while REC outstanding */
                return;
        }
 retry:
        if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
-               fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+               fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp));
        else
-               fc_fcp_recovery(fsp);
+               fc_fcp_recovery(fsp, FC_TIMED_OUT);
 }
 
 /**
@@ -1445,7 +1482,6 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
                         * making progress.
                         */
                        rpriv->flags &= ~FC_RP_FLAGS_REC_SUPPORTED;
-                       fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT);
                        break;
                case ELS_RJT_LOGIC:
                case ELS_RJT_UNAB:
@@ -1460,7 +1496,7 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
                                fc_fcp_retry_cmd(fsp);
                                break;
                        }
-                       fc_fcp_recovery(fsp);
+                       fc_fcp_recovery(fsp, FC_ERROR);
                        break;
                }
        } else if (opcode == ELS_LS_ACC) {
@@ -1498,12 +1534,12 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
                        }
                        fc_fcp_srr(fsp, r_ctl, offset);
                } else if (e_stat & ESB_ST_SEQ_INIT) {
-
+                       unsigned int rec_tov = get_fsp_rec_tov(fsp);
                        /*
                         * The remote port has the initiative, so just
                         * keep waiting for it to complete.
                         */
-                       fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+                       fc_fcp_timer_set(fsp, rec_tov);
                } else {
 
                        /*
@@ -1575,7 +1611,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
                if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
                        fc_fcp_rec(fsp);
                else
-                       fc_fcp_recovery(fsp);
+                       fc_fcp_recovery(fsp, FC_ERROR);
                break;
        }
        fc_fcp_unlock_pkt(fsp);
@@ -1587,9 +1623,9 @@ out:
  * fc_fcp_recovery() - Handler for fcp_pkt recovery
  * @fsp: The FCP pkt that needs to be aborted
  */
-static void fc_fcp_recovery(struct fc_fcp_pkt *fsp)
+static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code)
 {
-       fsp->status_code = FC_CMD_RECOVERY;
+       fsp->status_code = code;
        fsp->cdb_status = 0;
        fsp->io_status = 0;
        /*
@@ -1616,6 +1652,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
        struct fcp_srr *srr;
        struct fc_frame *fp;
        u8 cdb_op;
+       unsigned int rec_tov;
 
        rport = fsp->rport;
        rpriv = rport->dd_data;
@@ -1640,8 +1677,9 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
                       rpriv->local_port->port_id, FC_TYPE_FCP,
                       FC_FCTL_REQ, 0);
 
+       rec_tov = get_fsp_rec_tov(fsp);
        seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
-                                     fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
+                                     fsp, jiffies_to_msecs(rec_tov));
        if (!seq)
                goto retry;
 
@@ -1665,6 +1703,7 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
        struct fc_fcp_pkt *fsp = arg;
        struct fc_frame_header *fh;
+       unsigned int rec_tov;
 
        if (IS_ERR(fp)) {
                fc_fcp_srr_error(fsp, fp);
@@ -1691,11 +1730,12 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
        switch (fc_frame_payload_op(fp)) {
        case ELS_LS_ACC:
                fsp->recov_retry = 0;
-               fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
+               rec_tov = get_fsp_rec_tov(fsp);
+               fc_fcp_timer_set(fsp, rec_tov);
                break;
        case ELS_LS_RJT:
        default:
-               fc_fcp_recovery(fsp);
+               fc_fcp_recovery(fsp, FC_ERROR);
                break;
        }
        fc_fcp_unlock_pkt(fsp);
@@ -1721,7 +1761,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
                if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
                        fc_fcp_rec(fsp);
                else
-                       fc_fcp_recovery(fsp);
+                       fc_fcp_recovery(fsp, FC_TIMED_OUT);
                break;
        case -FC_EX_CLOSED:                     /* e.g., link failure */
                /* fall through */
@@ -1753,7 +1793,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));
@@ -1820,19 +1860,17 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
        if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
                fsp->req_flags = FC_SRB_READ;
                stats->InputRequests++;
-               stats->InputMegabytes = fsp->data_len;
+               stats->InputBytes += fsp->data_len;
        } else if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
                fsp->req_flags = FC_SRB_WRITE;
                stats->OutputRequests++;
-               stats->OutputMegabytes = fsp->data_len;
+               stats->OutputBytes += fsp->data_len;
        } else {
                fsp->req_flags = 0;
                stats->ControlRequests++;
        }
        put_cpu();
 
-       fsp->tgt_flags = rpriv->flags;
-
        init_timer(&fsp->timer);
        fsp->timer.data = (unsigned long)fsp;
 
@@ -1851,6 +1889,8 @@ out:
        spin_lock_irq(lport->host->host_lock);
        return rc;
 }
+
+DEF_SCSI_QCMD(fc_queuecommand)
 EXPORT_SYMBOL(fc_queuecommand);
 
 /**
@@ -1944,18 +1984,29 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
                break;
        case FC_CMD_ABORTED:
                FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
-                          "due to FC_CMD_ABORTED\n");
+                         "due to FC_CMD_ABORTED\n");
                sc_cmd->result = (DID_ERROR << 16) | fsp->io_status;
                break;
-       case FC_CMD_RECOVERY:
-               sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status;
-               break;
        case FC_CMD_RESET:
+               FC_FCP_DBG(fsp, "Returning DID_RESET to scsi-ml "
+                          "due to FC_CMD_RESET\n");
                sc_cmd->result = (DID_RESET << 16);
                break;
        case FC_HRD_ERROR:
+               FC_FCP_DBG(fsp, "Returning DID_NO_CONNECT to scsi-ml "
+                          "due to FC_HRD_ERROR\n");
                sc_cmd->result = (DID_NO_CONNECT << 16);
                break;
+       case FC_CRC_ERROR:
+               FC_FCP_DBG(fsp, "Returning DID_PARITY to scsi-ml "
+                          "due to FC_CRC_ERROR\n");
+               sc_cmd->result = (DID_PARITY << 16);
+               break;
+       case FC_TIMED_OUT:
+               FC_FCP_DBG(fsp, "Returning DID_BUS_BUSY to scsi-ml "
+                          "due to FC_TIMED_OUT\n");
+               sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status;
+               break;
        default:
                FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml "
                           "due to unknown error\n");
@@ -2002,7 +2053,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
        fsp = CMD_SP(sc_cmd);
        if (!fsp) {
                /* command completed while scsi eh was setting up */
-               spin_unlock_irqrestore(lport->host->host_lock, flags);
+               spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
                return SUCCESS;
        }
        /* grab a ref so the fsp and sc_cmd cannot be relased from under us */
index 16d2162dda1f62a5fb075f2120e0fc890c12d375..eea0c3541b712fc7fad71704fc62e46a10dd85ee 100644 (file)
@@ -66,9 +66,21 @@ extern unsigned int fc_debug_logging;
 
 #define FC_FCP_DBG(pkt, fmt, args...)                                  \
        FC_CHECK_LOGGING(FC_FCP_LOGGING,                                \
-                        printk(KERN_INFO "host%u: fcp: %6.6x: " fmt,   \
+       {                                                               \
+               if ((pkt)->seq_ptr) {                                   \
+                       struct fc_exch *_ep = NULL;                     \
+                       _ep = fc_seq_exch((pkt)->seq_ptr);              \
+                       printk(KERN_INFO "host%u: fcp: %6.6x: "         \
+                               "xid %04x-%04x: " fmt,                  \
                                (pkt)->lp->host->host_no,               \
-                               pkt->rport->port_id, ##args))
+                               (pkt)->rport->port_id,                  \
+                               (_ep)->oxid, (_ep)->rxid, ##args);      \
+               } else {                                                \
+                       printk(KERN_INFO "host%u: fcp: %6.6x: " fmt,    \
+                               (pkt)->lp->host->host_no,               \
+                               (pkt)->rport->port_id, ##args);         \
+               }                                                       \
+       })
 
 #define FC_EXCH_DBG(exch, fmt, args...)                                        \
        FC_CHECK_LOGGING(FC_EXCH_LOGGING,                               \
index 9be63edbf8fb9095624222f7dc6398957e0abd28..c5a10f94f845bd938419e7094c3a58b936b712b1 100644 (file)
@@ -288,6 +288,8 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
        struct fc_lport *lport = shost_priv(shost);
        struct timespec v0, v1;
        unsigned int cpu;
+       u64 fcp_in_bytes = 0;
+       u64 fcp_out_bytes = 0;
 
        fcoe_stats = &lport->host_stats;
        memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
@@ -310,10 +312,12 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
                fcoe_stats->fcp_input_requests += stats->InputRequests;
                fcoe_stats->fcp_output_requests += stats->OutputRequests;
                fcoe_stats->fcp_control_requests += stats->ControlRequests;
-               fcoe_stats->fcp_input_megabytes += stats->InputMegabytes;
-               fcoe_stats->fcp_output_megabytes += stats->OutputMegabytes;
+               fcp_in_bytes += stats->InputBytes;
+               fcp_out_bytes += stats->OutputBytes;
                fcoe_stats->link_failure_count += stats->LinkFailureCount;
        }
+       fcoe_stats->fcp_input_megabytes = div_u64(fcp_in_bytes, 1000000);
+       fcoe_stats->fcp_output_megabytes = div_u64(fcp_out_bytes, 1000000);
        fcoe_stats->lip_count = -1;
        fcoe_stats->nos_count = -1;
        fcoe_stats->loss_of_sync_count = -1;
@@ -1703,8 +1707,10 @@ static int fc_lport_els_request(struct fc_bsg_job *job,
        info->sg = job->reply_payload.sg_list;
 
        if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
-                                    NULL, info, tov))
+                                    NULL, info, tov)) {
+               kfree(info);
                return -ECOMM;
+       }
        return 0;
 }
 
@@ -1762,8 +1768,10 @@ static int fc_lport_ct_request(struct fc_bsg_job *job,
        info->sg = job->reply_payload.sg_list;
 
        if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
-                                    NULL, info, tov))
+                                    NULL, info, tov)) {
+               kfree(info);
                return -ECOMM;
+       }
        return 0;
 }
 
index a84ef13ed74adf2a0e0d1dd81c644b2f3c9514a7..a7175adab32dd4278967a0a49e276ed09f8d6a1b 100644 (file)
@@ -652,7 +652,7 @@ void fc_rport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
        FC_RPORT_DBG(rdata, "Received a FLOGI %s\n", fc_els_resp_type(fp));
 
        if (fp == ERR_PTR(-FC_EX_CLOSED))
-               return;
+               goto put;
 
        mutex_lock(&rdata->rp_mutex);
 
@@ -689,6 +689,7 @@ out:
        fc_frame_free(fp);
 err:
        mutex_unlock(&rdata->rp_mutex);
+put:
        kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
        return;
 bad:
index 633e09036357828b87e1df84dacec85beda24492..7551abe409002455798f6d71f0ffed5454fb9963 100644 (file)
@@ -539,11 +539,12 @@ void __iscsi_get_task(struct iscsi_task *task)
 }
 EXPORT_SYMBOL_GPL(__iscsi_get_task);
 
-static void __iscsi_put_task(struct iscsi_task *task)
+void __iscsi_put_task(struct iscsi_task *task)
 {
        if (atomic_dec_and_test(&task->refcount))
                iscsi_free_task(task);
 }
+EXPORT_SYMBOL_GPL(__iscsi_put_task);
 
 void iscsi_put_task(struct iscsi_task *task)
 {
@@ -1599,7 +1600,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 +1737,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 fe8b74c706d21d4449887070133db3294d1b50ac..5257fdfe699ae6d1c853d0de0a68f2f51986e054 100644 (file)
 #include <scsi/scsi_transport_sas.h>
 #include "../scsi_sas_internal.h"
 
+static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy *phy)
+{
+       struct sas_ha_struct *sas_ha = phy->ha;
+
+       if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
+                  SAS_ADDR_SIZE) != 0 || (sas_ha->strict_wide_ports &&
+            memcmp(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE) != 0))
+               return false;
+       return true;
+}
+
 /**
  * sas_form_port -- add this phy to a port
  * @phy: the phy of interest
@@ -45,8 +56,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
        unsigned long flags;
 
        if (port) {
-               if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
-                          SAS_ADDR_SIZE) != 0)
+               if (!phy_is_wideport_member(port, phy))
                        sas_deform_port(phy);
                else {
                        SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
@@ -62,9 +72,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
                port = sas_ha->sas_port[i];
                spin_lock(&port->phy_list_lock);
                if (*(u64 *) port->sas_addr &&
-                   memcmp(port->attached_sas_addr,
-                          phy->attached_sas_addr, SAS_ADDR_SIZE) == 0 &&
-                   port->num_phys > 0) {
+                   phy_is_wideport_member(port, phy) && port->num_phys > 0) {
                        /* wide port */
                        SAS_DPRINTK("phy%d matched wide port%d\n", phy->id,
                                    port->id);
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 196de40b906c487c0287b56ac3c27c5f4b66a5ee..746dd3d7a092c4b46a66620283ef04849442cf25 100644 (file)
@@ -464,12 +464,29 @@ struct unsol_rcv_ct_ctx {
 #define UNSOL_VALID    0x00000001
 };
 
+#define LPFC_USER_LINK_SPEED_AUTO      0       /* auto select (default)*/
+#define LPFC_USER_LINK_SPEED_1G                1       /* 1 Gigabaud */
+#define LPFC_USER_LINK_SPEED_2G                2       /* 2 Gigabaud */
+#define LPFC_USER_LINK_SPEED_4G                4       /* 4 Gigabaud */
+#define LPFC_USER_LINK_SPEED_8G                8       /* 8 Gigabaud */
+#define LPFC_USER_LINK_SPEED_10G       10      /* 10 Gigabaud */
+#define LPFC_USER_LINK_SPEED_16G       16      /* 16 Gigabaud */
+#define LPFC_USER_LINK_SPEED_MAX       LPFC_USER_LINK_SPEED_16G
+#define LPFC_USER_LINK_SPEED_BITMAP ((1 << LPFC_USER_LINK_SPEED_16G) | \
+                                    (1 << LPFC_USER_LINK_SPEED_10G) | \
+                                    (1 << LPFC_USER_LINK_SPEED_8G) | \
+                                    (1 << LPFC_USER_LINK_SPEED_4G) | \
+                                    (1 << LPFC_USER_LINK_SPEED_2G) | \
+                                    (1 << LPFC_USER_LINK_SPEED_1G) | \
+                                    (1 << LPFC_USER_LINK_SPEED_AUTO))
+#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16"
+
 struct lpfc_hba {
        /* SCSI interface function jump table entries */
        int (*lpfc_new_scsi_buf)
                (struct lpfc_vport *, int);
        struct lpfc_scsi_buf * (*lpfc_get_scsi_buf)
-               (struct lpfc_hba *);
+               (struct lpfc_hba *, struct lpfc_nodelist *);
        int (*lpfc_scsi_prep_dma_buf)
                (struct lpfc_hba *, struct lpfc_scsi_buf *);
        void (*lpfc_scsi_unprep_dma_buf)
@@ -545,7 +562,7 @@ struct lpfc_hba {
        uint32_t hba_flag;      /* hba generic flags */
 #define HBA_ERATT_HANDLED      0x1 /* This flag is set when eratt handled */
 #define DEFER_ERATT            0x2 /* Deferred error attention in progress */
-#define HBA_FCOE_SUPPORT       0x4 /* HBA function supports FCOE */
+#define HBA_FCOE_MODE          0x4 /* HBA function in FCoE Mode */
 #define HBA_SP_QUEUE_EVT       0x8 /* Slow-path qevt posted to worker thread*/
 #define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */
 #define FCP_XRI_ABORT_EVENT    0x20
@@ -557,6 +574,7 @@ struct lpfc_hba {
 #define HBA_FIP_SUPPORT                0x800 /* FIP support in HBA */
 #define HBA_AER_ENABLED                0x1000 /* AER enabled with HBA */
 #define HBA_DEVLOSS_TMO         0x2000 /* HBA in devloss timeout */
+#define HBA_RRQ_ACTIVE         0x4000 /* process the rrq active list */
        uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
        struct lpfc_dmabuf slim2p;
 
@@ -606,6 +624,7 @@ struct lpfc_hba {
        /* HBA Config Parameters */
        uint32_t cfg_ack0;
        uint32_t cfg_enable_npiv;
+       uint32_t cfg_enable_rrq;
        uint32_t cfg_topology;
        uint32_t cfg_link_speed;
        uint32_t cfg_cr_delay;
@@ -716,6 +735,7 @@ struct lpfc_hba {
        uint32_t total_scsi_bufs;
        struct list_head lpfc_iocb_list;
        uint32_t total_iocbq_bufs;
+       struct list_head active_rrq_list;
        spinlock_t hbalock;
 
        /* pci_mem_pools */
@@ -728,6 +748,7 @@ struct lpfc_hba {
 
        mempool_t *mbox_mem_pool;
        mempool_t *nlp_mem_pool;
+       mempool_t *rrq_pool;
 
        struct fc_host_statistics link_stats;
        enum intr_type_t intr_type;
@@ -784,6 +805,7 @@ struct lpfc_hba {
        unsigned long skipped_hb;
        struct timer_list hb_tmofunc;
        uint8_t hb_outstanding;
+       struct timer_list rrq_tmr;
        enum hba_temp_state over_temp_state;
        /* ndlp reference management */
        spinlock_t ndlp_lock;
index c1cbec01345d0849a027748cdad9425e72094356..c06491b5862f04137fde8c01f36543460e7818ad 100644 (file)
 #define LPFC_MIN_DEVLOSS_TMO 1
 #define LPFC_MAX_DEVLOSS_TMO 255
 
-#define LPFC_MAX_LINK_SPEED 8
-#define LPFC_LINK_SPEED_BITMAP 0x00000117
-#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8"
-
 /**
  * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules
  * @incr: integer to convert.
@@ -463,7 +459,7 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
                if (phba->sli.sli_flag & LPFC_MENLO_MAINT)
                        len += snprintf(buf + len, PAGE_SIZE-len,
                                        "   Menlo Maint Mode\n");
-               else if (phba->fc_topology == TOPOLOGY_LOOP) {
+               else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                        if (vport->fc_flag & FC_PUBLIC_LOOP)
                                len += snprintf(buf + len, PAGE_SIZE-len,
                                                "   Public Loop\n");
@@ -1981,6 +1977,13 @@ lpfc_param_show(enable_npiv);
 lpfc_param_init(enable_npiv, 1, 0, 1);
 static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, lpfc_enable_npiv_show, NULL);
 
+int lpfc_enable_rrq;
+module_param(lpfc_enable_rrq, int, 0);
+MODULE_PARM_DESC(lpfc_enable_rrq, "Enable RRQ functionality");
+lpfc_param_show(enable_rrq);
+lpfc_param_init(enable_rrq, 0, 0, 1);
+static DEVICE_ATTR(lpfc_enable_rrq, S_IRUGO, lpfc_enable_rrq_show, NULL);
+
 /*
 # lpfc_suppress_link_up:  Bring link up at initialization
 #            0x0  = bring link up (issue MBX_INIT_LINK)
@@ -2837,14 +2840,8 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = {
 /*
 # lpfc_link_speed: Link speed selection for initializing the Fibre Channel
 # connection.
-#       0  = auto select (default)
-#       1  = 1 Gigabaud
-#       2  = 2 Gigabaud
-#       4  = 4 Gigabaud
-#       8  = 8 Gigabaud
-# Value range is [0,8]. Default value is 0.
+# Value range is [0,16]. Default value is 0.
 */
-
 /**
  * lpfc_link_speed_set - Set the adapters link speed
  * @phba: lpfc_hba pointer.
@@ -2869,7 +2866,7 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
        struct Scsi_Host  *shost = class_to_shost(dev);
        struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
        struct lpfc_hba   *phba = vport->phba;
-       int val = 0;
+       int val = LPFC_USER_LINK_SPEED_AUTO;
        int nolip = 0;
        const char *val_buf = buf;
        int err;
@@ -2885,15 +2882,20 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
        if (sscanf(val_buf, "%i", &val) != 1)
                return -EINVAL;
 
-       if (((val == LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
-               ((val == LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
-               ((val == LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
-               ((val == LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
-               ((val == LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)))
+       if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
+           ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
+           ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
+           ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
+           ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
+           ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb))) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "2879 lpfc_link_speed attribute cannot be set "
+                               "to %d. Speed is not supported by this port.\n",
+                               val);
                return -EINVAL;
-
-       if ((val >= 0 && val <= 8)
-               && (LPFC_LINK_SPEED_BITMAP & (1 << val))) {
+       }
+       if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
+           (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
                prev_val = phba->cfg_link_speed;
                phba->cfg_link_speed = val;
                if (nolip)
@@ -2906,11 +2908,9 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
                } else
                        return strlen(buf);
        }
-
        lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-               "%d:0469 lpfc_link_speed attribute cannot be set to %d, "
-               "allowed range is [0, 8]\n",
-               phba->brd_no, val);
+               "0469 lpfc_link_speed attribute cannot be set to %d, "
+               "allowed values are ["LPFC_LINK_SPEED_STRING"]\n", val);
        return -EINVAL;
 }
 
@@ -2938,8 +2938,8 @@ lpfc_param_show(link_speed)
 static int
 lpfc_link_speed_init(struct lpfc_hba *phba, int val)
 {
-       if ((val >= 0 && val <= LPFC_MAX_LINK_SPEED)
-               && (LPFC_LINK_SPEED_BITMAP & (1 << val))) {
+       if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
+           (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
                phba->cfg_link_speed = val;
                return 0;
        }
@@ -2947,12 +2947,12 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val)
                        "0405 lpfc_link_speed attribute cannot "
                        "be set to %d, allowed values are "
                        "["LPFC_LINK_SPEED_STRING"]\n", val);
-       phba->cfg_link_speed = 0;
+       phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
        return -EINVAL;
 }
 
 static DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR,
-               lpfc_link_speed_show, lpfc_link_speed_store);
+                  lpfc_link_speed_show, lpfc_link_speed_store);
 
 /*
 # lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
@@ -3305,12 +3305,12 @@ LPFC_ATTR_R(fcp_eq_count, LPFC_FP_EQN_DEF, LPFC_FP_EQN_MIN, LPFC_FP_EQN_MAX,
 LPFC_ATTR_R(enable_hba_reset, 1, 0, 1, "Enable HBA resets from the driver.");
 
 /*
-# lpfc_enable_hba_heartbeat: Enable HBA heartbeat timer..
+# lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer..
 #       0  = HBA Heartbeat disabled
 #       1  = HBA Heartbeat enabled (default)
 # Value range is [0,1]. Default value is 1.
 */
-LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat.");
+LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
 
 /*
 # lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF)
@@ -3401,6 +3401,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
        &dev_attr_lpfc_fdmi_on,
        &dev_attr_lpfc_max_luns,
        &dev_attr_lpfc_enable_npiv,
+       &dev_attr_lpfc_enable_rrq,
        &dev_attr_nport_evt_cnt,
        &dev_attr_board_mode,
        &dev_attr_max_vpi,
@@ -3798,8 +3799,7 @@ sysfs_mbox_read(struct file *filp, struct kobject *kobj,
                        }
                        break;
                case MBX_READ_SPARM64:
-               case MBX_READ_LA:
-               case MBX_READ_LA64:
+               case MBX_READ_TOPOLOGY:
                case MBX_REG_LOGIN:
                case MBX_REG_LOGIN64:
                case MBX_CONFIG_PORT:
@@ -3989,7 +3989,7 @@ lpfc_get_host_port_type(struct Scsi_Host *shost)
        if (vport->port_type == LPFC_NPIV_PORT) {
                fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
        } else if (lpfc_is_link_up(phba)) {
-               if (phba->fc_topology == TOPOLOGY_LOOP) {
+               if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                        if (vport->fc_flag & FC_PUBLIC_LOOP)
                                fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
                        else
@@ -4058,23 +4058,26 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
 
        if (lpfc_is_link_up(phba)) {
                switch(phba->fc_linkspeed) {
-                       case LA_1GHZ_LINK:
-                               fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
+               case LPFC_LINK_SPEED_1GHZ:
+                       fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
                        break;
-                       case LA_2GHZ_LINK:
-                               fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
+               case LPFC_LINK_SPEED_2GHZ:
+                       fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
                        break;
-                       case LA_4GHZ_LINK:
-                               fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
+               case LPFC_LINK_SPEED_4GHZ:
+                       fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
                        break;
-                       case LA_8GHZ_LINK:
-                               fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
+               case LPFC_LINK_SPEED_8GHZ:
+                       fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
                        break;
-                       case LA_10GHZ_LINK:
-                               fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
+               case LPFC_LINK_SPEED_10GHZ:
+                       fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
                        break;
-                       default:
-                               fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+               case LPFC_LINK_SPEED_16GHZ:
+                       fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
+                       break;
+               default:
+                       fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
                        break;
                }
        } else
@@ -4097,7 +4100,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
        spin_lock_irq(shost->host_lock);
 
        if ((vport->fc_flag & FC_FABRIC) ||
-           ((phba->fc_topology == TOPOLOGY_LOOP) &&
+           ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
             (vport->fc_flag & FC_PUBLIC_LOOP)))
                node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
        else
@@ -4208,11 +4211,11 @@ lpfc_get_stats(struct Scsi_Host *shost)
        hs->invalid_crc_count -= lso->invalid_crc_count;
        hs->error_frames -= lso->error_frames;
 
-       if (phba->hba_flag & HBA_FCOE_SUPPORT) {
+       if (phba->hba_flag & HBA_FCOE_MODE) {
                hs->lip_count = -1;
                hs->nos_count = (phba->link_events >> 1);
                hs->nos_count -= lso->link_events;
-       } else if (phba->fc_topology == TOPOLOGY_LOOP) {
+       } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                hs->lip_count = (phba->fc_eventTag >> 1);
                hs->lip_count -= lso->link_events;
                hs->nos_count = -1;
@@ -4303,7 +4306,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
        lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
        lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
        lso->error_frames = pmb->un.varRdLnk.crcCnt;
-       if (phba->hba_flag & HBA_FCOE_SUPPORT)
+       if (phba->hba_flag & HBA_FCOE_MODE)
                lso->link_events = (phba->link_events >> 1);
        else
                lso->link_events = (phba->fc_eventTag >> 1);
@@ -4615,6 +4618,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
        lpfc_link_speed_init(phba, lpfc_link_speed);
        lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
        lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
+       lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
        lpfc_use_msi_init(phba, lpfc_use_msi);
        lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
        lpfc_fcp_wq_count_init(phba, lpfc_fcp_wq_count);
index 7260c3af555a0723924553fb362cb88aee742cd5..0dd43bb916181a4496c3ca4ea01179e2912e9999 100644 (file)
@@ -162,7 +162,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
                        struct lpfc_iocbq *cmdiocbq,
                        struct lpfc_iocbq *rspiocbq)
 {
-       unsigned long iflags;
        struct bsg_job_data *dd_data;
        struct fc_bsg_job *job;
        IOCB_t *rsp;
@@ -173,9 +172,10 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
        int rc = 0;
 
        spin_lock_irqsave(&phba->ct_ev_lock, flags);
-       dd_data = cmdiocbq->context1;
+       dd_data = cmdiocbq->context2;
        if (!dd_data) {
                spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+               lpfc_sli_release_iocbq(phba, cmdiocbq);
                return;
        }
 
@@ -183,17 +183,9 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
        job = iocb->set_job;
        job->dd_data = NULL; /* so timeout handler does not reply */
 
-       spin_lock_irqsave(&phba->hbalock, iflags);
-       cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
-       if (cmdiocbq->context2 && rspiocbq)
-               memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
-                      &rspiocbq->iocb, sizeof(IOCB_t));
-       spin_unlock_irqrestore(&phba->hbalock, iflags);
-
        bmp = iocb->bmp;
-       rspiocbq = iocb->rspiocbq;
        rsp = &rspiocbq->iocb;
-       ndlp = iocb->ndlp;
+       ndlp = cmdiocbq->context1;
 
        pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
                     job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -220,7 +212,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
                        rsp->un.genreq64.bdl.bdeSize;
 
        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
-       lpfc_sli_release_iocbq(phba, rspiocbq);
        lpfc_sli_release_iocbq(phba, cmdiocbq);
        lpfc_nlp_put(ndlp);
        kfree(bmp);
@@ -247,9 +238,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
        struct ulp_bde64 *bpl = NULL;
        uint32_t timeout;
        struct lpfc_iocbq *cmdiocbq = NULL;
-       struct lpfc_iocbq *rspiocbq = NULL;
        IOCB_t *cmd;
-       IOCB_t *rsp;
        struct lpfc_dmabuf *bmp = NULL;
        int request_nseg;
        int reply_nseg;
@@ -296,17 +285,10 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
        }
 
        cmd = &cmdiocbq->iocb;
-       rspiocbq = lpfc_sli_get_iocbq(phba);
-       if (!rspiocbq) {
-               rc = -ENOMEM;
-               goto free_cmdiocbq;
-       }
-
-       rsp = &rspiocbq->iocb;
        bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
        if (!bmp->virt) {
                rc = -ENOMEM;
-               goto free_rspiocbq;
+               goto free_cmdiocbq;
        }
 
        INIT_LIST_HEAD(&bmp->list);
@@ -358,14 +340,12 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
        cmd->ulpTimeout = timeout;
 
        cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
-       cmdiocbq->context1 = dd_data;
-       cmdiocbq->context2 = rspiocbq;
+       cmdiocbq->context1 = ndlp;
+       cmdiocbq->context2 = dd_data;
        dd_data->type = TYPE_IOCB;
        dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
-       dd_data->context_un.iocb.rspiocbq = rspiocbq;
        dd_data->context_un.iocb.set_job = job;
        dd_data->context_un.iocb.bmp = bmp;
-       dd_data->context_un.iocb.ndlp = ndlp;
 
        if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
                creg_val = readl(phba->HCregaddr);
@@ -391,8 +371,6 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
 
        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 
-free_rspiocbq:
-       lpfc_sli_release_iocbq(phba, rspiocbq);
 free_cmdiocbq:
        lpfc_sli_release_iocbq(phba, cmdiocbq);
 free_bmp:
@@ -1220,7 +1198,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
        int rc = 0;
 
        spin_lock_irqsave(&phba->ct_ev_lock, flags);
-       dd_data = cmdiocbq->context1;
+       dd_data = cmdiocbq->context2;
        /* normal completion and timeout crossed paths, already done */
        if (!dd_data) {
                spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
@@ -1369,8 +1347,8 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
        ctiocb->context3 = bmp;
 
        ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp;
-       ctiocb->context1 = dd_data;
-       ctiocb->context2 = NULL;
+       ctiocb->context2 = dd_data;
+       ctiocb->context1 = ndlp;
        dd_data->type = TYPE_IOCB;
        dd_data->context_un.iocb.cmdiocbq = ctiocb;
        dd_data->context_un.iocb.rspiocbq = NULL;
@@ -1641,7 +1619,7 @@ job_error:
  * This function obtains a remote port login id so the diag loopback test
  * can send and receive its own unsolicited CT command.
  **/
-static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
+static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t *rpi)
 {
        LPFC_MBOXQ_t *mbox;
        struct lpfc_dmabuf *dmabuff;
@@ -1651,10 +1629,14 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
        if (!mbox)
                return -ENOMEM;
 
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               *rpi = lpfc_sli4_alloc_rpi(phba);
        status = lpfc_reg_rpi(phba, 0, phba->pport->fc_myDID,
-                               (uint8_t *)&phba->pport->fc_sparam, mbox, 0);
+                             (uint8_t *)&phba->pport->fc_sparam, mbox, *rpi);
        if (status) {
                mempool_free(mbox, phba->mbox_mem_pool);
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       lpfc_sli4_free_rpi(phba, *rpi);
                return -ENOMEM;
        }
 
@@ -1668,6 +1650,8 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
                kfree(dmabuff);
                if (status != MBX_TIMEOUT)
                        mempool_free(mbox, phba->mbox_mem_pool);
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       lpfc_sli4_free_rpi(phba, *rpi);
                return -ENODEV;
        }
 
@@ -1704,8 +1688,9 @@ static int lpfcdiag_loop_self_unreg(struct lpfc_hba *phba, uint16_t rpi)
                        mempool_free(mbox, phba->mbox_mem_pool);
                return -EIO;
        }
-
        mempool_free(mbox, phba->mbox_mem_pool);
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               lpfc_sli4_free_rpi(phba, rpi);
        return 0;
 }
 
@@ -2102,7 +2087,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
        uint32_t size;
        uint32_t full_size;
        size_t segment_len = 0, segment_offset = 0, current_offset = 0;
-       uint16_t rpi;
+       uint16_t rpi = 0;
        struct lpfc_iocbq *cmdiocbq, *rspiocbq;
        IOCB_t *cmd, *rsp;
        struct lpfc_sli_ct_request *ctreq;
@@ -2162,7 +2147,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
                goto loopback_test_exit;
        }
 
-       if (size >= BUF_SZ_4K) {
+       if (full_size >= BUF_SZ_4K) {
                /*
                 * Allocate memory for ioctl data. If buffer is bigger than 64k,
                 * then we allocate 64k and re-use that buffer over and over to
@@ -2171,7 +2156,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
                 * problem with GET_FCPTARGETMAPPING...
                 */
                if (size <= (64 * 1024))
-                       total_mem = size;
+                       total_mem = full_size;
                else
                        total_mem = 64 * 1024;
        } else
@@ -2189,7 +2174,6 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
        sg_copy_to_buffer(job->request_payload.sg_list,
                                job->request_payload.sg_cnt,
                                ptr, size);
-
        rc = lpfcdiag_loop_self_reg(phba, &rpi);
        if (rc)
                goto loopback_test_exit;
@@ -2601,12 +2585,11 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
                        phba->wait_4_mlo_maint_flg = 1;
                } else if (mb->un.varWords[0] == SETVAR_MLORST) {
                        phba->link_flag &= ~LS_LOOPBACK_MODE;
-                       phba->fc_topology = TOPOLOGY_PT_PT;
+                       phba->fc_topology = LPFC_TOPOLOGY_PT_PT;
                }
                break;
        case MBX_READ_SPARM64:
-       case MBX_READ_LA:
-       case MBX_READ_LA64:
+       case MBX_READ_TOPOLOGY:
        case MBX_REG_LOGIN:
        case MBX_REG_LOGIN64:
        case MBX_CONFIG_PORT:
index a5f5a093a8a46752e5c802da8a593de4510e7e6e..17fde522c84aec70339b366181178bb6ffd6dbc5 100644 (file)
@@ -31,7 +31,7 @@ void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
 
 void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *);
-int lpfc_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
+int lpfc_read_topology(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
 void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_issue_clear_la(struct lpfc_hba *, struct lpfc_vport *);
 void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -40,7 +40,7 @@ int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *, int);
 void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_reg_rpi(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
-                LPFC_MBOXQ_t *, uint32_t);
+                LPFC_MBOXQ_t *, uint16_t);
 void lpfc_set_var(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
 void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
 void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
@@ -64,7 +64,7 @@ void lpfc_cleanup_pending_mbox(struct lpfc_vport *);
 int lpfc_linkdown(struct lpfc_hba *);
 void lpfc_linkdown_port(struct lpfc_vport *);
 void lpfc_port_link_failure(struct lpfc_vport *);
-void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_read_topology(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
 void lpfc_retry_pport_discovery(struct lpfc_hba *);
@@ -121,6 +121,7 @@ void lpfc_end_rscn(struct lpfc_vport *);
 int lpfc_els_chk_latt(struct lpfc_vport *);
 int lpfc_els_abort_flogi(struct lpfc_hba *);
 int lpfc_initial_flogi(struct lpfc_vport *);
+void lpfc_issue_init_vfi(struct lpfc_vport *);
 int lpfc_initial_fdisc(struct lpfc_vport *);
 int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t);
 int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
@@ -415,5 +416,13 @@ struct lpfc_iocbq *lpfc_sli_ringtx_get(struct lpfc_hba *,
 int __lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
        struct lpfc_iocbq *, uint32_t);
 uint32_t lpfc_drain_txq(struct lpfc_hba *);
-
-
+void lpfc_clr_rrq_active(struct lpfc_hba *, uint16_t, struct lpfc_node_rrq *);
+int lpfc_test_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *, uint16_t);
+void lpfc_handle_rrq_active(struct lpfc_hba *);
+int lpfc_send_rrq(struct lpfc_hba *, struct lpfc_node_rrq *);
+int lpfc_set_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *,
+       uint16_t, uint16_t, uint16_t);
+void lpfc_cleanup_wt_rrqs(struct lpfc_hba *);
+void lpfc_cleanup_vports_rrqs(struct lpfc_vport *);
+struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t,
+       uint32_t);
index 463b74902ac4b2b32368e2b99227321515e1d314..c004fa9a681ea65894d0e869b10d6aebcf106364 100644 (file)
 #include "lpfc_vport.h"
 #include "lpfc_debugfs.h"
 
-#define HBA_PORTSPEED_UNKNOWN               0  /* Unknown - transceiver
-                                                * incapable of reporting */
-#define HBA_PORTSPEED_1GBIT                 1  /* 1 GBit/sec */
-#define HBA_PORTSPEED_2GBIT                 2  /* 2 GBit/sec */
-#define HBA_PORTSPEED_4GBIT                 8   /* 4 GBit/sec */
-#define HBA_PORTSPEED_8GBIT                16   /* 8 GBit/sec */
-#define HBA_PORTSPEED_10GBIT                4  /* 10 GBit/sec */
-#define HBA_PORTSPEED_NOT_NEGOTIATED        5  /* Speed not established */
+/* FDMI Port Speed definitions */
+#define HBA_PORTSPEED_1GBIT            0x0001  /* 1 GBit/sec */
+#define HBA_PORTSPEED_2GBIT            0x0002  /* 2 GBit/sec */
+#define HBA_PORTSPEED_4GBIT            0x0008  /* 4 GBit/sec */
+#define HBA_PORTSPEED_10GBIT           0x0004  /* 10 GBit/sec */
+#define HBA_PORTSPEED_8GBIT            0x0010  /* 8 GBit/sec */
+#define HBA_PORTSPEED_16GBIT           0x0020  /* 16 GBit/sec */
+#define HBA_PORTSPEED_UNKNOWN          0x0800  /* Unknown */
 
 #define FOURBYTES      4
 
@@ -1593,8 +1593,10 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
                        ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
 
                        ae->un.SupportSpeed = 0;
+                       if (phba->lmt & LMT_16Gb)
+                               ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT;
                        if (phba->lmt & LMT_10Gb)
-                               ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
+                               ae->un.SupportSpeed |= HBA_PORTSPEED_10GBIT;
                        if (phba->lmt & LMT_8Gb)
                                ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT;
                        if (phba->lmt & LMT_4Gb)
@@ -1612,24 +1614,26 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
                        ae->ad.bits.AttrType = be16_to_cpu(PORT_SPEED);
                        ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
                        switch(phba->fc_linkspeed) {
-                               case LA_1GHZ_LINK:
-                                       ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
+                       case LPFC_LINK_SPEED_1GHZ:
+                               ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
                                break;
-                               case LA_2GHZ_LINK:
-                                       ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
+                       case LPFC_LINK_SPEED_2GHZ:
+                               ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
                                break;
-                               case LA_4GHZ_LINK:
-                                       ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
+                       case LPFC_LINK_SPEED_4GHZ:
+                               ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
                                break;
-                               case LA_8GHZ_LINK:
-                                       ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
+                       case LPFC_LINK_SPEED_8GHZ:
+                               ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
                                break;
-                               case LA_10GHZ_LINK:
-                                       ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
+                       case LPFC_LINK_SPEED_10GHZ:
+                               ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
                                break;
-                               default:
-                                       ae->un.PortSpeed =
-                                               HBA_PORTSPEED_UNKNOWN;
+                       case LPFC_LINK_SPEED_16GHZ:
+                               ae->un.PortSpeed = HBA_PORTSPEED_16GBIT;
+                               break;
+                       default:
+                               ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN;
                                break;
                        }
                        pab->ab.EntryCnt++;
index 7cae69de36f75eb90f55d4ba1ad69ad3a3fff8cd..1d84b63fccadf49eb9f39374ef3b7d1b163d2d8c 100644 (file)
@@ -68,6 +68,12 @@ struct lpfc_fast_path_event {
        } un;
 };
 
+#define LPFC_SLI4_MAX_XRI      1024    /* Used to make the ndlp's xri_bitmap */
+#define XRI_BITMAP_ULONGS (LPFC_SLI4_MAX_XRI / BITS_PER_LONG)
+struct lpfc_node_rrqs {
+       unsigned long xri_bitmap[XRI_BITMAP_ULONGS];
+};
+
 struct lpfc_nodelist {
        struct list_head nlp_listp;
        struct lpfc_name nlp_portname;
@@ -110,8 +116,19 @@ struct lpfc_nodelist {
        atomic_t cmd_pending;
        uint32_t cmd_qdepth;
        unsigned long last_change_time;
+       struct lpfc_node_rrqs active_rrqs;
        struct lpfc_scsicmd_bkt *lat_data;      /* Latency data */
 };
+struct lpfc_node_rrq {
+       struct list_head list;
+       uint16_t xritag;
+       uint16_t send_rrq;
+       uint16_t rxid;
+       uint32_t         nlp_DID;               /* FC D_ID of entry */
+       struct lpfc_vport *vport;
+       struct lpfc_nodelist *ndlp;
+       unsigned long rrq_stop_time;
+};
 
 /* Defines for nlp_flag (uint32) */
 #define NLP_IGNR_REG_CMPL  0x00000001 /* Rcvd rscn before we cmpl reg login */
@@ -136,7 +153,7 @@ struct lpfc_nodelist {
 #define NLP_NODEV_REMOVE   0x08000000  /* Defer removal till discovery ends */
 #define NLP_TARGET_REMOVE  0x10000000   /* Target remove in process */
 #define NLP_SC_REQ         0x20000000  /* Target requires authentication */
-#define NLP_RPI_VALID      0x80000000  /* nlp_rpi is valid */
+#define NLP_RPI_REGISTERED 0x80000000  /* nlp_rpi is valid */
 
 /* ndlp usage management macros */
 #define NLP_CHK_NODE_ACT(ndlp)         (((ndlp)->nlp_usg_map \
index 884f4d321799cffda5bb5ea56295d4166fb0b32c..c62d567cc8457b6ba880247f081f3efcb61ec4c2 100644 (file)
@@ -375,7 +375,8 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
                err = 4;
                goto fail;
        }
-       rc = lpfc_reg_rpi(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, 0);
+       rc = lpfc_reg_rpi(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox,
+                         ndlp->nlp_rpi);
        if (rc) {
                err = 5;
                goto fail_free_mbox;
@@ -523,7 +524,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        phba->fc_edtovResol = sp->cmn.edtovResolution;
        phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
 
-       if (phba->fc_topology == TOPOLOGY_LOOP) {
+       if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                spin_lock_irq(shost->host_lock);
                vport->fc_flag |= FC_PUBLIC_LOOP;
                spin_unlock_irq(shost->host_lock);
@@ -832,6 +833,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                if (lpfc_els_retry(phba, cmdiocb, rspiocb))
                        goto out;
 
+               /* FLOGI failure */
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n",
+                                irsp->ulpStatus, irsp->un.ulpWord[4],
+                                irsp->ulpTimeout);
+
                /* FLOGI failed, so there is no fabric */
                spin_lock_irq(shost->host_lock);
                vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
@@ -843,13 +850,16 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                 */
                if (phba->alpa_map[0] == 0) {
                        vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
+                       if ((phba->sli_rev == LPFC_SLI_REV4) &&
+                           (!(vport->fc_flag & FC_VFI_REGISTERED) ||
+                            (vport->fc_prevDID != vport->fc_myDID))) {
+                               if (vport->fc_flag & FC_VFI_REGISTERED)
+                                       lpfc_sli4_unreg_all_rpis(vport);
+                               lpfc_issue_reg_vfi(vport);
+                               lpfc_nlp_put(ndlp);
+                               goto out;
+                       }
                }
-
-               /* FLOGI failure */
-               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
-                                "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n",
-                                irsp->ulpStatus, irsp->un.ulpWord[4],
-                                irsp->ulpTimeout);
                goto flogifail;
        }
        spin_lock_irq(shost->host_lock);
@@ -879,7 +889,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                 */
                if (sp->cmn.fPort)
                        rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp);
-               else if (!(phba->hba_flag & HBA_FCOE_SUPPORT))
+               else if (!(phba->hba_flag & HBA_FCOE_MODE))
                        rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
                else {
                        lpfc_printf_vlog(vport, KERN_ERR,
@@ -1014,7 +1024,9 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        if (sp->cmn.fcphHigh < FC_PH3)
                sp->cmn.fcphHigh = FC_PH3;
 
-       if  (phba->sli_rev == LPFC_SLI_REV4) {
+       if  ((phba->sli_rev == LPFC_SLI_REV4) &&
+            (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+             LPFC_SLI_INTF_IF_TYPE_0)) {
                elsiocb->iocb.ulpCt_h = ((SLI4_CT_FCFI >> 1) & 1);
                elsiocb->iocb.ulpCt_l = (SLI4_CT_FCFI & 1);
                /* FLOGI needs to be 3 for WQE FCFI */
@@ -1027,7 +1039,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                icmd->ulpCt_l = 0;
        }
 
-       if (phba->fc_topology != TOPOLOGY_LOOP) {
+       if (phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
                icmd->un.elsreq64.myID = 0;
                icmd->un.elsreq64.fl = 1;
        }
@@ -1281,6 +1293,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
        uint32_t rc, keepDID = 0;
        int  put_node;
        int  put_rport;
+       struct lpfc_node_rrqs rrq;
 
        /* Fabric nodes can have the same WWPN so we don't bother searching
         * by WWPN.  Just return the ndlp that was given to us.
@@ -1298,6 +1311,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 
        if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp))
                return ndlp;
+       memset(&rrq.xri_bitmap, 0, sizeof(new_ndlp->active_rrqs.xri_bitmap));
 
        if (!new_ndlp) {
                rc = memcmp(&ndlp->nlp_portname, name,
@@ -1318,12 +1332,25 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                if (!new_ndlp)
                        return ndlp;
                keepDID = new_ndlp->nlp_DID;
-       } else
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       memcpy(&rrq.xri_bitmap,
+                               &new_ndlp->active_rrqs.xri_bitmap,
+                               sizeof(new_ndlp->active_rrqs.xri_bitmap));
+       } else {
                keepDID = new_ndlp->nlp_DID;
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       memcpy(&rrq.xri_bitmap,
+                               &new_ndlp->active_rrqs.xri_bitmap,
+                               sizeof(new_ndlp->active_rrqs.xri_bitmap));
+       }
 
        lpfc_unreg_rpi(vport, new_ndlp);
        new_ndlp->nlp_DID = ndlp->nlp_DID;
        new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               memcpy(new_ndlp->active_rrqs.xri_bitmap,
+                       &ndlp->active_rrqs.xri_bitmap,
+                       sizeof(ndlp->active_rrqs.xri_bitmap));
 
        if (ndlp->nlp_flag & NLP_NPR_2B_DISC)
                new_ndlp->nlp_flag |= NLP_NPR_2B_DISC;
@@ -1362,12 +1389,20 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 
                /* Two ndlps cannot have the same did on the nodelist */
                ndlp->nlp_DID = keepDID;
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       memcpy(&ndlp->active_rrqs.xri_bitmap,
+                               &rrq.xri_bitmap,
+                               sizeof(ndlp->active_rrqs.xri_bitmap));
                lpfc_drop_node(vport, ndlp);
        }
        else {
                lpfc_unreg_rpi(vport, ndlp);
                /* Two ndlps cannot have the same did */
                ndlp->nlp_DID = keepDID;
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       memcpy(&ndlp->active_rrqs.xri_bitmap,
+                               &rrq.xri_bitmap,
+                               sizeof(ndlp->active_rrqs.xri_bitmap));
                lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
                /* Since we are swapping the ndlp passed in with the new one
                 * and the did has already been swapped, copy over the
@@ -1427,6 +1462,73 @@ lpfc_end_rscn(struct lpfc_vport *vport)
        }
 }
 
+/**
+ * lpfc_cmpl_els_rrq - Completion handled for els RRQs.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine will call the clear rrq function to free the rrq and
+ * clear the xri's bit in the ndlp's xri_bitmap. If the ndlp does not
+ * exist then the clear_rrq is still called because the rrq needs to
+ * be freed.
+ **/
+
+static void
+lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+                   struct lpfc_iocbq *rspiocb)
+{
+       struct lpfc_vport *vport = cmdiocb->vport;
+       IOCB_t *irsp;
+       struct lpfc_nodelist *ndlp;
+       struct lpfc_node_rrq *rrq;
+
+       /* we pass cmdiocb to state machine which needs rspiocb as well */
+       rrq = cmdiocb->context_un.rrq;
+       cmdiocb->context_un.rsp_iocb = rspiocb;
+
+       irsp = &rspiocb->iocb;
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
+               "RRQ cmpl:      status:x%x/x%x did:x%x",
+               irsp->ulpStatus, irsp->un.ulpWord[4],
+               irsp->un.elsreq64.remoteID);
+
+       ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
+       if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || ndlp != rrq->ndlp) {
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "2882 RRQ completes to NPort x%x "
+                                "with no ndlp. Data: x%x x%x x%x\n",
+                                irsp->un.elsreq64.remoteID,
+                                irsp->ulpStatus, irsp->un.ulpWord[4],
+                                irsp->ulpIoTag);
+               goto out;
+       }
+
+       /* rrq completes to NPort <nlp_DID> */
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "2880 RRQ completes to NPort x%x "
+                        "Data: x%x x%x x%x x%x x%x\n",
+                        ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
+                        irsp->ulpTimeout, rrq->xritag, rrq->rxid);
+
+       if (irsp->ulpStatus) {
+               /* Check for retry */
+               /* RRQ failed Don't print the vport to vport rjts */
+               if (irsp->ulpStatus != IOSTAT_LS_RJT ||
+                       (((irsp->un.ulpWord[4]) >> 16 != LSRJT_INVALID_CMD) &&
+                       ((irsp->un.ulpWord[4]) >> 16 != LSRJT_UNABLE_TPC)) ||
+                       (phba)->pport->cfg_log_verbose & LOG_ELS)
+                       lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "2881 RRQ failure DID:%06X Status:x%x/x%x\n",
+                                ndlp->nlp_DID, irsp->ulpStatus,
+                                irsp->un.ulpWord[4]);
+       }
+out:
+       if (rrq)
+               lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
+       lpfc_els_free_iocb(phba, cmdiocb);
+       return;
+}
 /**
  * lpfc_cmpl_els_plogi - Completion callback function for plogi
  * @phba: pointer to lpfc hba data structure.
@@ -2722,7 +2824,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        if (cmd == ELS_CMD_FLOGI) {
                                if (PCI_DEVICE_ID_HORNET ==
                                        phba->pcidev->device) {
-                                       phba->fc_topology = TOPOLOGY_LOOP;
+                                       phba->fc_topology = LPFC_TOPOLOGY_LOOP;
                                        phba->pport->fc_myDID = 0;
                                        phba->alpa_map[0] = 0;
                                        phba->alpa_map[1] = 0;
@@ -2877,7 +2979,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                retry = 1;
 
        if (((cmd == ELS_CMD_FLOGI) || (cmd == ELS_CMD_FDISC)) &&
-           (phba->fc_topology != TOPOLOGY_LOOP) &&
+           (phba->fc_topology != LPFC_TOPOLOGY_LOOP) &&
            !lpfc_error_lost_link(irsp)) {
                /* FLOGI retry policy */
                retry = 1;
@@ -3219,14 +3321,6 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
        struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
 
-       /*
-        * This routine is used to register and unregister in previous SLI
-        * modes.
-        */
-       if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) &&
-           (phba->sli_rev == LPFC_SLI_REV4))
-               lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi);
-
        pmb->context1 = NULL;
        pmb->context2 = NULL;
 
@@ -3903,6 +3997,47 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
        return 0;
 }
 
+/**
+ * lpfc_els_clear_rrq - Clear the rq that this rrq describes.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @iocb: pointer to the lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * Return
+ **/
+static void
+lpfc_els_clear_rrq(struct lpfc_vport *vport,
+      struct lpfc_iocbq *iocb, struct lpfc_nodelist *ndlp)
+{
+       struct lpfc_hba  *phba = vport->phba;
+       uint8_t *pcmd;
+       struct RRQ *rrq;
+       uint16_t rxid;
+       struct lpfc_node_rrq *prrq;
+
+
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) iocb->context2)->virt);
+       pcmd += sizeof(uint32_t);
+       rrq = (struct RRQ *)pcmd;
+       rxid = bf_get(rrq_oxid, rrq);
+
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                       "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x"
+                       " x%x x%x\n",
+                       bf_get(rrq_did, rrq),
+                       bf_get(rrq_oxid, rrq),
+                       rxid,
+                       iocb->iotag, iocb->iocb.ulpContext);
+
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
+               "Clear RRQ:  did:x%x flg:x%x exchg:x%.08x",
+               ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg);
+       prrq = lpfc_get_active_rrq(vport, rxid, ndlp->nlp_DID);
+       if (prrq)
+               lpfc_clr_rrq_active(phba, rxid, prrq);
+       return;
+}
+
 /**
  * lpfc_els_rsp_echo_acc - Issue echo acc response
  * @vport: pointer to a virtual N_Port data structure.
@@ -4597,7 +4732,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
 
        lpfc_set_disctmo(vport);
 
-       if (phba->fc_topology == TOPOLOGY_LOOP) {
+       if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                /* We should never receive a FLOGI in loop mode, ignore it */
                did = icmd->un.elsreq64.remoteID;
 
@@ -4792,6 +4927,8 @@ lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                 struct lpfc_nodelist *ndlp)
 {
        lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+       if (vport->phba->sli_rev == LPFC_SLI_REV4)
+               lpfc_els_clear_rrq(vport, cmdiocb, ndlp);
 }
 
 /**
@@ -4940,7 +5077,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        pcmd += sizeof(uint32_t); /* Skip past command */
        rps_rsp = (RPS_RSP *)pcmd;
 
-       if (phba->fc_topology != TOPOLOGY_LOOP)
+       if (phba->fc_topology != LPFC_TOPOLOGY_LOOP)
                status = 0x10;
        else
                status = 0x8;
@@ -5194,6 +5331,97 @@ reject_out:
        return 0;
 }
 
+/* lpfc_issue_els_rrq - Process an unsolicited rps iocb
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @did: DID of the target.
+ * @rrq: Pointer to the rrq struct.
+ *
+ * Build a ELS RRQ command and send it to the target. If the issue_iocb is
+ * Successful the the completion handler will clear the RRQ.
+ *
+ * Return codes
+ *   0 - Successfully sent rrq els iocb.
+ *   1 - Failed to send rrq els iocb.
+ **/
+static int
+lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+                       uint32_t did, struct lpfc_node_rrq *rrq)
+{
+       struct lpfc_hba  *phba = vport->phba;
+       struct RRQ *els_rrq;
+       IOCB_t *icmd;
+       struct lpfc_iocbq *elsiocb;
+       uint8_t *pcmd;
+       uint16_t cmdsize;
+       int ret;
+
+
+       if (ndlp != rrq->ndlp)
+               ndlp = rrq->ndlp;
+       if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+               return 1;
+
+       /* If ndlp is not NULL, we will bump the reference count on it */
+       cmdsize = (sizeof(uint32_t) + sizeof(struct RRQ));
+       elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp, did,
+                                    ELS_CMD_RRQ);
+       if (!elsiocb)
+               return 1;
+
+       icmd = &elsiocb->iocb;
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+
+       /* For RRQ request, remainder of payload is Exchange IDs */
+       *((uint32_t *) (pcmd)) = ELS_CMD_RRQ;
+       pcmd += sizeof(uint32_t);
+       els_rrq = (struct RRQ *) pcmd;
+
+       bf_set(rrq_oxid, els_rrq, rrq->xritag);
+       bf_set(rrq_rxid, els_rrq, rrq->rxid);
+       bf_set(rrq_did, els_rrq, vport->fc_myDID);
+       els_rrq->rrq = cpu_to_be32(els_rrq->rrq);
+       els_rrq->rrq_exchg = cpu_to_be32(els_rrq->rrq_exchg);
+
+
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
+               "Issue RRQ:     did:x%x",
+               did, rrq->xritag, rrq->rxid);
+       elsiocb->context_un.rrq = rrq;
+       elsiocb->iocb_cmpl = lpfc_cmpl_els_rrq;
+       ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
+
+       if (ret == IOCB_ERROR) {
+               lpfc_els_free_iocb(phba, elsiocb);
+               return 1;
+       }
+       return 0;
+}
+
+/**
+ * lpfc_send_rrq - Sends ELS RRQ if needed.
+ * @phba: pointer to lpfc hba data structure.
+ * @rrq: pointer to the active rrq.
+ *
+ * This routine will call the lpfc_issue_els_rrq if the rrq is
+ * still active for the xri. If this function returns a failure then
+ * the caller needs to clean up the RRQ by calling lpfc_clr_active_rrq.
+ *
+ * Returns 0 Success.
+ *         1 Failure.
+ **/
+int
+lpfc_send_rrq(struct lpfc_hba *phba, struct lpfc_node_rrq *rrq)
+{
+       struct lpfc_nodelist *ndlp = lpfc_findnode_did(rrq->vport,
+                                                       rrq->nlp_DID);
+       if (lpfc_test_rrq_active(phba, ndlp, rrq->xritag))
+               return lpfc_issue_els_rrq(rrq->vport, ndlp,
+                                        rrq->nlp_DID, rrq);
+       else
+               return 1;
+}
+
 /**
  * lpfc_els_rsp_rpl_acc - Issue an accept rpl els command
  * @vport: pointer to a host virtual N_Port data structure.
@@ -5482,7 +5710,7 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                    (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
                            sizeof(struct lpfc_name)))) {
                        /* This port has switched fabrics. FLOGI is required */
-                       lpfc_initial_flogi(vport);
+                       lpfc_issue_init_vfi(vport);
                } else {
                        /* FAN verified - skip FLOGI */
                        vport->fc_myDID = vport->fc_prevDID;
@@ -6201,7 +6429,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                        cmd, did, vport->port_state);
 
                /* Unsupported ELS command, reject */
-               rjt_err = LSRJT_INVALID_CMD;
+               rjt_err = LSRJT_CMD_UNSUPPORTED;
 
                /* Unknown ELS command <elsCmd> received from NPORT <did> */
                lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -6373,7 +6601,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
        if (!ndlp) {
                ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
                if (!ndlp) {
-                       if (phba->fc_topology == TOPOLOGY_LOOP) {
+                       if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                                lpfc_disc_start(vport);
                                return;
                        }
@@ -6386,7 +6614,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
        } else if (!NLP_CHK_NODE_ACT(ndlp)) {
                ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
                if (!ndlp) {
-                       if (phba->fc_topology == TOPOLOGY_LOOP) {
+                       if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                                lpfc_disc_start(vport);
                                return;
                        }
@@ -6408,18 +6636,31 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
        }
 
        if (vport->cfg_fdmi_on) {
-               ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
-                                         GFP_KERNEL);
+               /* If this is the first time, allocate an ndlp and initialize
+                * it. Otherwise, make sure the node is enabled and then do the
+                * login.
+                */
+               ndlp_fdmi = lpfc_findnode_did(vport, FDMI_DID);
+               if (!ndlp_fdmi) {
+                       ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
+                                                 GFP_KERNEL);
+                       if (ndlp_fdmi) {
+                               lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
+                               ndlp_fdmi->nlp_type |= NLP_FABRIC;
+                       } else
+                               return;
+               }
+               if (!NLP_CHK_NODE_ACT(ndlp_fdmi))
+                       ndlp_fdmi = lpfc_enable_node(vport,
+                                                    ndlp_fdmi,
+                                                    NLP_STE_NPR_NODE);
+
                if (ndlp_fdmi) {
-                       lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
-                       ndlp_fdmi->nlp_type |= NLP_FABRIC;
                        lpfc_nlp_set_state(vport, ndlp_fdmi,
-                               NLP_STE_PLOGI_ISSUE);
-                       lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID,
-                                            0);
+                                          NLP_STE_PLOGI_ISSUE);
+                       lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 0);
                }
        }
-       return;
 }
 
 /**
@@ -6497,7 +6738,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                        spin_unlock_irq(shost->host_lock);
                        if (vport->port_type == LPFC_PHYSICAL_PORT
                                && !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG))
-                               lpfc_initial_flogi(vport);
+                               lpfc_issue_init_vfi(vport);
                        else
                                lpfc_initial_fdisc(vport);
                        break;
@@ -6734,7 +6975,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
        vport->fc_flag &= ~FC_VPORT_LOGO_RCVD;
        vport->fc_flag |= FC_FABRIC;
-       if (vport->phba->fc_topology == TOPOLOGY_LOOP)
+       if (vport->phba->fc_topology == LPFC_TOPOLOGY_LOOP)
                vport->fc_flag |=  FC_PUBLIC_LOOP;
        spin_unlock_irq(shost->host_lock);
 
@@ -6844,7 +7085,9 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        icmd->un.elsreq64.myID = 0;
        icmd->un.elsreq64.fl = 1;
 
-       if  (phba->sli_rev == LPFC_SLI_REV4) {
+       if  ((phba->sli_rev == LPFC_SLI_REV4) &&
+            (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+             LPFC_SLI_INTF_IF_TYPE_0)) {
                /* FDISC needs to be 1 for WQE VPI */
                elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1;
                elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ;
@@ -7351,8 +7594,11 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
                          struct sli4_wcqe_xri_aborted *axri)
 {
        uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
+       uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
+
        struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
        unsigned long iflag = 0;
+       struct lpfc_nodelist *ndlp;
        struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
 
        spin_lock_irqsave(&phba->hbalock, iflag);
@@ -7361,11 +7607,14 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
                        &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
                if (sglq_entry->sli4_xritag == xri) {
                        list_del(&sglq_entry->list);
+                       ndlp = sglq_entry->ndlp;
+                       sglq_entry->ndlp = NULL;
                        list_add_tail(&sglq_entry->list,
                                &phba->sli4_hba.lpfc_sgl_list);
                        sglq_entry->state = SGL_FREED;
                        spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
                        spin_unlock_irqrestore(&phba->hbalock, iflag);
+                       lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1);
 
                        /* Check if TXQ queue needs to be serviced */
                        if (pring->txq_cnt)
index a5d1695dac3dcd73b1e5cae6651c46c602d57d20..f9f160ab2ee9184e1623b5a7495b4f377e42df93 100644 (file)
@@ -607,6 +607,8 @@ lpfc_work_done(struct lpfc_hba *phba)
 
        /* Process SLI4 events */
        if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) {
+               if (phba->hba_flag & HBA_RRQ_ACTIVE)
+                       lpfc_handle_rrq_active(phba);
                if (phba->hba_flag & FCP_XRI_ABORT_EVENT)
                        lpfc_sli4_fcp_xri_abort_event_proc(phba);
                if (phba->hba_flag & ELS_XRI_ABORT_EVENT)
@@ -966,6 +968,7 @@ lpfc_linkup(struct lpfc_hba *phba)
        struct lpfc_vport **vports;
        int i;
 
+       lpfc_cleanup_wt_rrqs(phba);
        phba->link_state = LPFC_LINK_UP;
 
        /* Unblock fabric iocbs if they are blocked */
@@ -1064,7 +1067,7 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 
        mempool_free(pmb, phba->mbox_mem_pool);
 
-       if (phba->fc_topology == TOPOLOGY_LOOP &&
+       if (phba->fc_topology == LPFC_TOPOLOGY_LOOP &&
            vport->fc_flag & FC_PUBLIC_LOOP &&
            !(vport->fc_flag & FC_LBIT)) {
                        /* Need to wait for FAN - use discovery timer
@@ -1078,9 +1081,8 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        /* Start discovery by sending a FLOGI. port_state is identically
         * LPFC_FLOGI while waiting for FLOGI cmpl
         */
-       if (vport->port_state != LPFC_FLOGI) {
+       if (vport->port_state != LPFC_FLOGI)
                lpfc_initial_flogi(vport);
-       }
        return;
 
 out:
@@ -1131,7 +1133,7 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
        if (vport->port_state != LPFC_FLOGI) {
                phba->hba_flag |= FCF_RR_INPROG;
                spin_unlock_irq(&phba->hbalock);
-               lpfc_initial_flogi(vport);
+               lpfc_issue_init_vfi(vport);
                goto out;
        }
        spin_unlock_irq(&phba->hbalock);
@@ -1353,7 +1355,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
                if (phba->pport->port_state != LPFC_FLOGI) {
                        phba->hba_flag |= FCF_RR_INPROG;
                        spin_unlock_irq(&phba->hbalock);
-                       lpfc_initial_flogi(phba->pport);
+                       lpfc_issue_init_vfi(phba->pport);
                        return;
                }
                spin_unlock_irq(&phba->hbalock);
@@ -2331,7 +2333,7 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                                phba->fcf.current_rec.fcf_indx, fcf_index);
                /* Wait 500 ms before retrying FLOGI to current FCF */
                msleep(500);
-               lpfc_initial_flogi(phba->pport);
+               lpfc_issue_init_vfi(phba->pport);
                goto out;
        }
 
@@ -2421,6 +2423,63 @@ out:
        lpfc_sli4_mbox_cmd_free(phba, mboxq);
 }
 
+/**
+ * lpfc_init_vfi_cmpl - Completion handler for init_vfi mbox command.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox data structure.
+ *
+ * This function handles completion of init vfi mailbox command.
+ */
+void
+lpfc_init_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+       struct lpfc_vport *vport = mboxq->vport;
+
+       if (mboxq->u.mb.mbxStatus && (mboxq->u.mb.mbxStatus != 0x4002)) {
+               lpfc_printf_vlog(vport, KERN_ERR,
+                               LOG_MBOX,
+                               "2891 Init VFI mailbox failed 0x%x\n",
+                               mboxq->u.mb.mbxStatus);
+               mempool_free(mboxq, phba->mbox_mem_pool);
+               lpfc_vport_set_state(vport, FC_VPORT_FAILED);
+               return;
+       }
+       lpfc_initial_flogi(vport);
+       mempool_free(mboxq, phba->mbox_mem_pool);
+       return;
+}
+
+/**
+ * lpfc_issue_init_vfi - Issue init_vfi mailbox command.
+ * @vport: pointer to lpfc_vport data structure.
+ *
+ * This function issue a init_vfi mailbox command to initialize the VFI and
+ * VPI for the physical port.
+ */
+void
+lpfc_issue_init_vfi(struct lpfc_vport *vport)
+{
+       LPFC_MBOXQ_t *mboxq;
+       int rc;
+       struct lpfc_hba *phba = vport->phba;
+
+       mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!mboxq) {
+               lpfc_printf_vlog(vport, KERN_ERR,
+                       LOG_MBOX, "2892 Failed to allocate "
+                       "init_vfi mailbox\n");
+               return;
+       }
+       lpfc_init_vfi(mboxq, vport);
+       mboxq->mbox_cmpl = lpfc_init_vfi_cmpl;
+       rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
+       if (rc == MBX_NOT_FINISHED) {
+               lpfc_printf_vlog(vport, KERN_ERR,
+                       LOG_MBOX, "2893 Failed to issue init_vfi mailbox\n");
+               mempool_free(mboxq, vport->phba->mbox_mem_pool);
+       }
+}
+
 /**
  * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command.
  * @phba: pointer to lpfc hba data structure.
@@ -2528,7 +2587,7 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
                                                     FC_VPORT_FAILED);
                                continue;
                        }
-                       if (phba->fc_topology == TOPOLOGY_LOOP) {
+                       if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                                lpfc_vport_set_state(vports[i],
                                                     FC_VPORT_LINKDOWN);
                                continue;
@@ -2564,7 +2623,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                         "2018 REG_VFI mbxStatus error x%x "
                         "HBA state x%x\n",
                         mboxq->u.mb.mbxStatus, vport->port_state);
-               if (phba->fc_topology == TOPOLOGY_LOOP) {
+               if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                        /* FLOGI failed, use loop map to make discovery list */
                        lpfc_disc_list_loopmap(vport);
                        /* Start discovery */
@@ -2582,8 +2641,18 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
        spin_unlock_irq(shost->host_lock);
 
        if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
-               lpfc_start_fdiscs(phba);
-               lpfc_do_scr_ns_plogi(phba, vport);
+               /* For private loop just start discovery and we are done. */
+               if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
+                   (phba->alpa_map[0] == 0) &&
+                   !(vport->fc_flag & FC_PUBLIC_LOOP)) {
+                       /* Use loop map to make discovery list */
+                       lpfc_disc_list_loopmap(vport);
+                       /* Start discovery */
+                       lpfc_disc_start(vport);
+               } else {
+                       lpfc_start_fdiscs(phba);
+                       lpfc_do_scr_ns_plogi(phba, vport);
+               }
        }
 
 fail_free_mem:
@@ -2644,7 +2713,7 @@ out:
 }
 
 static void
-lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
+lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
 {
        struct lpfc_vport *vport = phba->pport;
        LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL;
@@ -2654,31 +2723,24 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
        struct fcf_record *fcf_record;
 
        spin_lock_irq(&phba->hbalock);
-       switch (la->UlnkSpeed) {
-       case LA_1GHZ_LINK:
-               phba->fc_linkspeed = LA_1GHZ_LINK;
-               break;
-       case LA_2GHZ_LINK:
-               phba->fc_linkspeed = LA_2GHZ_LINK;
-               break;
-       case LA_4GHZ_LINK:
-               phba->fc_linkspeed = LA_4GHZ_LINK;
-               break;
-       case LA_8GHZ_LINK:
-               phba->fc_linkspeed = LA_8GHZ_LINK;
-               break;
-       case LA_10GHZ_LINK:
-               phba->fc_linkspeed = LA_10GHZ_LINK;
+       switch (bf_get(lpfc_mbx_read_top_link_spd, la)) {
+       case LPFC_LINK_SPEED_1GHZ:
+       case LPFC_LINK_SPEED_2GHZ:
+       case LPFC_LINK_SPEED_4GHZ:
+       case LPFC_LINK_SPEED_8GHZ:
+       case LPFC_LINK_SPEED_10GHZ:
+       case LPFC_LINK_SPEED_16GHZ:
+               phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la);
                break;
        default:
-               phba->fc_linkspeed = LA_UNKNW_LINK;
+               phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN;
                break;
        }
 
-       phba->fc_topology = la->topology;
+       phba->fc_topology = bf_get(lpfc_mbx_read_top_topology, la);
        phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
 
-       if (phba->fc_topology == TOPOLOGY_LOOP) {
+       if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
 
                /* if npiv is enabled and this adapter supports npiv log
@@ -2689,11 +2751,11 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
                                "1309 Link Up Event npiv not supported in loop "
                                "topology\n");
                                /* Get Loop Map information */
-               if (la->il)
+               if (bf_get(lpfc_mbx_read_top_il, la))
                        vport->fc_flag |= FC_LBIT;
 
-               vport->fc_myDID = la->granted_AL_PA;
-               i = la->un.lilpBde64.tus.f.bdeSize;
+               vport->fc_myDID = bf_get(lpfc_mbx_read_top_alpa_granted, la);
+               i = la->lilpBde64.tus.f.bdeSize;
 
                if (i == 0) {
                        phba->alpa_map[0] = 0;
@@ -2764,7 +2826,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
                goto out;
        }
 
-       if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) {
+       if (!(phba->hba_flag & HBA_FCOE_MODE)) {
                cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
                if (!cfglink_mbox)
                        goto out;
@@ -2874,17 +2936,17 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
 
 
 /*
- * This routine handles processing a READ_LA mailbox
+ * This routine handles processing a READ_TOPOLOGY mailbox
  * command upon completion. It is setup in the LPFC_MBOXQ
  * as the completion routine when the command is
  * handed off to the SLI layer.
  */
 void
-lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
        struct lpfc_vport *vport = pmb->vport;
        struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
-       READ_LA_VAR *la;
+       struct lpfc_mbx_read_top *la;
        MAILBOX_t *mb = &pmb->u.mb;
        struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
 
@@ -2897,15 +2959,15 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                                mb->mbxStatus, vport->port_state);
                lpfc_mbx_issue_link_down(phba);
                phba->link_state = LPFC_HBA_ERROR;
-               goto lpfc_mbx_cmpl_read_la_free_mbuf;
+               goto lpfc_mbx_cmpl_read_topology_free_mbuf;
        }
 
-       la = (READ_LA_VAR *) &pmb->u.mb.un.varReadLA;
+       la = (struct lpfc_mbx_read_top *) &pmb->u.mb.un.varReadTop;
 
        memcpy(&phba->alpa_map[0], mp->virt, 128);
 
        spin_lock_irq(shost->host_lock);
-       if (la->pb)
+       if (bf_get(lpfc_mbx_read_top_pb, la))
                vport->fc_flag |= FC_BYPASSED_MODE;
        else
                vport->fc_flag &= ~FC_BYPASSED_MODE;
@@ -2914,41 +2976,48 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        if ((phba->fc_eventTag  < la->eventTag) ||
            (phba->fc_eventTag == la->eventTag)) {
                phba->fc_stat.LinkMultiEvent++;
-               if (la->attType == AT_LINK_UP)
+               if (bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP)
                        if (phba->fc_eventTag != 0)
                                lpfc_linkdown(phba);
        }
 
        phba->fc_eventTag = la->eventTag;
        spin_lock_irq(&phba->hbalock);
-       if (la->mm)
+       if (bf_get(lpfc_mbx_read_top_mm, la))
                phba->sli.sli_flag |= LPFC_MENLO_MAINT;
        else
                phba->sli.sli_flag &= ~LPFC_MENLO_MAINT;
        spin_unlock_irq(&phba->hbalock);
 
        phba->link_events++;
-       if (la->attType == AT_LINK_UP && (!la->mm)) {
+       if ((bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP) &&
+           (!bf_get(lpfc_mbx_read_top_mm, la))) {
                phba->fc_stat.LinkUp++;
                if (phba->link_flag & LS_LOOPBACK_MODE) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
                                        "1306 Link Up Event in loop back mode "
                                        "x%x received Data: x%x x%x x%x x%x\n",
                                        la->eventTag, phba->fc_eventTag,
-                                       la->granted_AL_PA, la->UlnkSpeed,
+                                       bf_get(lpfc_mbx_read_top_alpa_granted,
+                                              la),
+                                       bf_get(lpfc_mbx_read_top_link_spd, la),
                                        phba->alpa_map[0]);
                } else {
                        lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
                                        "1303 Link Up Event x%x received "
                                        "Data: x%x x%x x%x x%x x%x x%x %d\n",
                                        la->eventTag, phba->fc_eventTag,
-                                       la->granted_AL_PA, la->UlnkSpeed,
+                                       bf_get(lpfc_mbx_read_top_alpa_granted,
+                                              la),
+                                       bf_get(lpfc_mbx_read_top_link_spd, la),
                                        phba->alpa_map[0],
-                                       la->mm, la->fa,
+                                       bf_get(lpfc_mbx_read_top_mm, la),
+                                       bf_get(lpfc_mbx_read_top_fa, la),
                                        phba->wait_4_mlo_maint_flg);
                }
                lpfc_mbx_process_link_up(phba, la);
-       } else if (la->attType == AT_LINK_DOWN) {
+       } else if (bf_get(lpfc_mbx_read_top_att_type, la) ==
+                  LPFC_ATT_LINK_DOWN) {
                phba->fc_stat.LinkDown++;
                if (phba->link_flag & LS_LOOPBACK_MODE) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
@@ -2964,11 +3033,13 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                                "Data: x%x x%x x%x x%x x%x\n",
                                la->eventTag, phba->fc_eventTag,
                                phba->pport->port_state, vport->fc_flag,
-                               la->mm, la->fa);
+                               bf_get(lpfc_mbx_read_top_mm, la),
+                               bf_get(lpfc_mbx_read_top_fa, la));
                }
                lpfc_mbx_issue_link_down(phba);
        }
-       if (la->mm && la->attType == AT_LINK_UP) {
+       if ((bf_get(lpfc_mbx_read_top_mm, la)) &&
+           (bf_get(lpfc_mbx_read_top_att_type, la) == LPFC_ATT_LINK_UP)) {
                if (phba->link_state != LPFC_LINK_DOWN) {
                        phba->fc_stat.LinkDown++;
                        lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
@@ -2996,14 +3067,15 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                }
        }
 
-       if (la->fa) {
-               if (la->mm)
+       if (bf_get(lpfc_mbx_read_top_fa, la)) {
+               if (bf_get(lpfc_mbx_read_top_mm, la))
                        lpfc_issue_clear_la(phba, vport);
                lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
-                               "1311 fa %d\n", la->fa);
+                               "1311 fa %d\n",
+                               bf_get(lpfc_mbx_read_top_fa, la));
        }
 
-lpfc_mbx_cmpl_read_la_free_mbuf:
+lpfc_mbx_cmpl_read_topology_free_mbuf:
        lpfc_mbuf_free(phba, mp->virt, mp->phys);
        kfree(mp);
        mempool_free(pmb, phba->mbox_mem_pool);
@@ -3030,8 +3102,8 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND)
                ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
 
-       if (ndlp->nlp_flag &  NLP_IGNR_REG_CMPL ||
-               ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) {
+       if (ndlp->nlp_flag & NLP_IGNR_REG_CMPL ||
+           ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) {
                /* We rcvd a rscn after issuing this
                 * mbox reg login, we may have cycled
                 * back through the state and be
@@ -3043,10 +3115,6 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                spin_lock_irq(shost->host_lock);
                ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
                spin_unlock_irq(shost->host_lock);
-               if (phba->sli_rev == LPFC_SLI_REV4)
-                       lpfc_sli4_free_rpi(phba,
-                               pmb->u.mb.un.varRegLogin.rpi);
-
        } else
                /* Good status, call state machine */
                lpfc_disc_state_machine(vport, ndlp, pmb,
@@ -3092,6 +3160,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        spin_unlock_irq(shost->host_lock);
        vport->unreg_vpi_cmpl = VPORT_OK;
        mempool_free(pmb, phba->mbox_mem_pool);
+       lpfc_cleanup_vports_rrqs(vport);
        /*
         * This shost reference might have been taken at the beginning of
         * lpfc_vport_delete()
@@ -3333,7 +3402,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                kfree(mp);
                mempool_free(pmb, phba->mbox_mem_pool);
 
-               if (phba->fc_topology == TOPOLOGY_LOOP) {
+               if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                        /* FLOGI failed, use loop map to make discovery list */
                        lpfc_disc_list_loopmap(vport);
 
@@ -3355,7 +3424,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        }
 
        ndlp->nlp_rpi = mb->un.varWords[0];
-       ndlp->nlp_flag |= NLP_RPI_VALID;
+       ndlp->nlp_flag |= NLP_RPI_REGISTERED;
        ndlp->nlp_type |= NLP_FABRIC;
        lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 
@@ -3413,7 +3482,7 @@ out:
                /* If no other thread is using the ndlp, free it */
                lpfc_nlp_not_used(ndlp);
 
-               if (phba->fc_topology == TOPOLOGY_LOOP) {
+               if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
                        /*
                         * RegLogin failed, use loop map to make discovery
                         * list
@@ -3429,7 +3498,7 @@ out:
        }
 
        ndlp->nlp_rpi = mb->un.varWords[0];
-       ndlp->nlp_flag |= NLP_RPI_VALID;
+       ndlp->nlp_flag |= NLP_RPI_REGISTERED;
        ndlp->nlp_type |= NLP_FABRIC;
        lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 
@@ -3762,6 +3831,8 @@ lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        NLP_INT_NODE_ACT(ndlp);
        atomic_set(&ndlp->cmd_pending, 0);
        ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
+       if (vport->phba->sli_rev == LPFC_SLI_REV4)
+               ndlp->nlp_rpi = lpfc_sli4_alloc_rpi(vport->phba);
 }
 
 struct lpfc_nodelist *
@@ -3975,7 +4046,7 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
         * by firmware with a no rpi error.
         */
        psli = &phba->sli;
-       if (ndlp->nlp_flag & NLP_RPI_VALID) {
+       if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
                /* Now process each ring */
                for (i = 0; i < psli->num_rings; i++) {
                        pring = &psli->ring[i];
@@ -4023,7 +4094,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        LPFC_MBOXQ_t    *mbox;
        int rc;
 
-       if (ndlp->nlp_flag & NLP_RPI_VALID) {
+       if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
                mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
                if (mbox) {
                        lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox);
@@ -4035,8 +4106,9 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
                }
                lpfc_no_rpi(phba, ndlp);
 
-               ndlp->nlp_rpi = 0;
-               ndlp->nlp_flag &= ~NLP_RPI_VALID;
+               if (phba->sli_rev != LPFC_SLI_REV4)
+                       ndlp->nlp_rpi = 0;
+               ndlp->nlp_flag &= ~NLP_RPI_REGISTERED;
                ndlp->nlp_flag &= ~NLP_NPR_ADISC;
                return 1;
        }
@@ -4059,11 +4131,16 @@ lpfc_unreg_hba_rpis(struct lpfc_hba *phba)
        int i;
 
        vports = lpfc_create_vport_work_array(phba);
+       if (!vports) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+                       "2884 Vport array allocation failed \n");
+               return;
+       }
        for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
                shost = lpfc_shost_from_vport(vports[i]);
                spin_lock_irq(shost->host_lock);
                list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) {
-                       if (ndlp->nlp_flag & NLP_RPI_VALID) {
+                       if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
                                /* The mempool_alloc might sleep */
                                spin_unlock_irq(shost->host_lock);
                                lpfc_unreg_rpi(vports[i], ndlp);
@@ -4192,9 +4269,6 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
                                kfree(mp);
                        }
                        list_del(&mb->list);
-                       if (phba->sli_rev == LPFC_SLI_REV4)
-                               lpfc_sli4_free_rpi(phba,
-                                        mb->u.mb.un.varRegLogin.rpi);
                        mempool_free(mb, phba->mbox_mem_pool);
                        /* We shall not invoke the lpfc_nlp_put to decrement
                         * the ndlp reference count as we are in the process
@@ -4236,15 +4310,15 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 
        lpfc_cancel_retry_delay_tmo(vport, ndlp);
        if ((ndlp->nlp_flag & NLP_DEFER_RM) &&
-               !(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
-           !(ndlp->nlp_flag & NLP_RPI_VALID)) {
+           !(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
+           !(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
                /* For this case we need to cleanup the default rpi
                 * allocated by the firmware.
                 */
                if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))
                        != NULL) {
                        rc = lpfc_reg_rpi(phba, vport->vpi, ndlp->nlp_DID,
-                           (uint8_t *) &vport->fc_sparam, mbox, 0);
+                           (uint8_t *) &vport->fc_sparam, mbox, ndlp->nlp_rpi);
                        if (rc) {
                                mempool_free(mbox, phba->mbox_mem_pool);
                        }
@@ -4436,7 +4510,7 @@ lpfc_disc_list_loopmap(struct lpfc_vport *vport)
        if (!lpfc_is_link_up(phba))
                return;
 
-       if (phba->fc_topology != TOPOLOGY_LOOP)
+       if (phba->fc_topology != LPFC_TOPOLOGY_LOOP)
                return;
 
        /* Check for loop map present or not */
@@ -4788,7 +4862,10 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
                        }
                }
                if (vport->port_state != LPFC_FLOGI) {
-                       lpfc_initial_flogi(vport);
+                       if (phba->sli_rev <= LPFC_SLI_REV3)
+                               lpfc_initial_flogi(vport);
+                       else
+                               lpfc_issue_init_vfi(vport);
                        return;
                }
                break;
@@ -4979,7 +5056,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        pmb->context2 = NULL;
 
        ndlp->nlp_rpi = mb->un.varWords[0];
-       ndlp->nlp_flag |= NLP_RPI_VALID;
+       ndlp->nlp_flag |= NLP_RPI_REGISTERED;
        ndlp->nlp_type |= NLP_FABRIC;
        lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 
@@ -5103,6 +5180,8 @@ lpfc_nlp_release(struct kref *kref)
        spin_lock_irqsave(&phba->ndlp_lock, flags);
        NLP_CLR_NODE_ACT(ndlp);
        spin_unlock_irqrestore(&phba->ndlp_lock, flags);
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
 
        /* free ndlp memory for final ndlp release */
        if (NLP_CHK_FREE_REQ(ndlp)) {
@@ -5254,6 +5333,10 @@ lpfc_fcf_inuse(struct lpfc_hba *phba)
 
        vports = lpfc_create_vport_work_array(phba);
 
+       /* If driver cannot allocate memory, indicate fcf is in use */
+       if (!vports)
+               return 1;
+
        for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
                shost = lpfc_shost_from_vport(vports[i]);
                spin_lock_irq(shost->host_lock);
@@ -5269,7 +5352,7 @@ lpfc_fcf_inuse(struct lpfc_hba *phba)
                                        "logged in\n",
                                        ndlp->nlp_rpi, ndlp->nlp_DID,
                                        ndlp->nlp_flag);
-                               if (ndlp->nlp_flag & NLP_RPI_VALID)
+                               if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
                                        ret = 1;
                        }
                }
@@ -5550,7 +5633,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
         * registered, do nothing.
         */
        spin_lock_irq(&phba->hbalock);
-       if (!(phba->hba_flag & HBA_FCOE_SUPPORT) ||
+       if (!(phba->hba_flag & HBA_FCOE_MODE) ||
            !(phba->fcf.fcf_flag & FCF_REGISTERED) ||
            !(phba->hba_flag & HBA_FIP_SUPPORT) ||
            (phba->fcf.fcf_flag & FCF_DISCOVERY) ||
index 9b833345646525c52b736f4f388e18f3f18695c4..96ed3ba6ba952fd7db3d64bc355548797fc735ea 100644 (file)
@@ -880,6 +880,24 @@ struct  RLS_RSP {          /* Structure is in Big Endian format */
        uint32_t crcCnt;
 };
 
+struct RRQ {                   /* Structure is in Big Endian format */
+       uint32_t rrq;
+#define rrq_rsvd_SHIFT         24
+#define rrq_rsvd_MASK          0x000000ff
+#define rrq_rsvd_WORD          rrq
+#define rrq_did_SHIFT          0
+#define rrq_did_MASK           0x00ffffff
+#define rrq_did_WORD           rrq
+       uint32_t rrq_exchg;
+#define rrq_oxid_SHIFT         16
+#define rrq_oxid_MASK          0xffff
+#define rrq_oxid_WORD          rrq_exchg
+#define rrq_rxid_SHIFT         0
+#define rrq_rxid_MASK          0xffff
+#define rrq_rxid_WORD          rrq_exchg
+};
+
+
 struct RTV_RSP {               /* Structure is in Big Endian format */
        uint32_t ratov;
        uint32_t edtov;
@@ -1172,7 +1190,10 @@ typedef struct {
 #define PCI_VENDOR_ID_EMULEX        0x10df
 #define PCI_DEVICE_ID_FIREFLY       0x1ae5
 #define PCI_DEVICE_ID_PROTEUS_VF    0xe100
+#define PCI_DEVICE_ID_BALIUS        0xe131
 #define PCI_DEVICE_ID_PROTEUS_PF    0xe180
+#define PCI_DEVICE_ID_LANCER_FC     0xe200
+#define PCI_DEVICE_ID_LANCER_FCOE   0xe260
 #define PCI_DEVICE_ID_SAT_SMB       0xf011
 #define PCI_DEVICE_ID_SAT_MID       0xf015
 #define PCI_DEVICE_ID_RFLY          0xf095
@@ -1189,6 +1210,7 @@ typedef struct {
 #define PCI_DEVICE_ID_SAT           0xf100
 #define PCI_DEVICE_ID_SAT_SCSP      0xf111
 #define PCI_DEVICE_ID_SAT_DCSP      0xf112
+#define PCI_DEVICE_ID_FALCON        0xf180
 #define PCI_DEVICE_ID_SUPERFLY      0xf700
 #define PCI_DEVICE_ID_DRAGONFLY     0xf800
 #define PCI_DEVICE_ID_CENTAUR       0xf900
@@ -1210,8 +1232,6 @@ typedef struct {
 #define PCI_VENDOR_ID_SERVERENGINE  0x19a2
 #define PCI_DEVICE_ID_TIGERSHARK    0x0704
 #define PCI_DEVICE_ID_TOMCAT        0x0714
-#define PCI_DEVICE_ID_FALCON        0xf180
-#define PCI_DEVICE_ID_BALIUS        0xe131
 
 #define JEDEC_ID_ADDRESS            0x0080001c
 #define FIREFLY_JEDEC_ID            0x1ACC
@@ -1368,7 +1388,6 @@ typedef struct {          /* FireFly BIU registers */
 #define MBX_READ_LNK_STAT   0x12
 #define MBX_REG_LOGIN       0x13
 #define MBX_UNREG_LOGIN     0x14
-#define MBX_READ_LA         0x15
 #define MBX_CLEAR_LA        0x16
 #define MBX_DUMP_MEMORY     0x17
 #define MBX_DUMP_CONTEXT    0x18
@@ -1402,7 +1421,7 @@ typedef struct {          /* FireFly BIU registers */
 #define MBX_READ_SPARM64    0x8D
 #define MBX_READ_RPI64      0x8F
 #define MBX_REG_LOGIN64     0x93
-#define MBX_READ_LA64       0x95
+#define MBX_READ_TOPOLOGY   0x95
 #define MBX_REG_VPI        0x96
 #define MBX_UNREG_VPI      0x97
 
@@ -1823,12 +1842,13 @@ typedef struct {
 #define FLAGS_IMED_ABORT             0x04000   /* Bit 14 */
 
        uint32_t link_speed;
-#define LINK_SPEED_AUTO 0       /* Auto selection */
-#define LINK_SPEED_1G   1       /* 1 Gigabaud */
-#define LINK_SPEED_2G   2       /* 2 Gigabaud */
-#define LINK_SPEED_4G   4       /* 4 Gigabaud */
-#define LINK_SPEED_8G   8       /* 8 Gigabaud */
-#define LINK_SPEED_10G   16      /* 10 Gigabaud */
+#define LINK_SPEED_AUTO 0x0     /* Auto selection */
+#define LINK_SPEED_1G   0x1     /* 1 Gigabaud */
+#define LINK_SPEED_2G   0x2     /* 2 Gigabaud */
+#define LINK_SPEED_4G   0x4     /* 4 Gigabaud */
+#define LINK_SPEED_8G   0x8     /* 8 Gigabaud */
+#define LINK_SPEED_10G  0x10    /* 10 Gigabaud */
+#define LINK_SPEED_16G  0x11    /* 16 Gigabaud */
 
 } INIT_LINK_VAR;
 
@@ -1999,6 +2019,7 @@ typedef struct {
 #define LMT_4Gb       0x040
 #define LMT_8Gb       0x080
 #define LMT_10Gb      0x100
+#define LMT_16Gb      0x200
        uint32_t rsvd2;
        uint32_t rsvd3;
        uint32_t max_xri;
@@ -2394,100 +2415,93 @@ typedef struct {
 #endif
 } UNREG_D_ID_VAR;
 
-/* Structure for MB Command READ_LA (21) */
-/* Structure for MB Command READ_LA64 (0x95) */
-
-typedef struct {
+/* Structure for MB Command READ_TOPOLOGY (0x95) */
+struct lpfc_mbx_read_top {
        uint32_t eventTag;      /* Event tag */
-#ifdef __BIG_ENDIAN_BITFIELD
-       uint32_t rsvd1:19;
-       uint32_t fa:1;
-       uint32_t mm:1;          /* Menlo Maintenance mode enabled */
-       uint32_t rx:1;
-       uint32_t pb:1;
-       uint32_t il:1;
-       uint32_t attType:8;
-#else  /*  __LITTLE_ENDIAN_BITFIELD */
-       uint32_t attType:8;
-       uint32_t il:1;
-       uint32_t pb:1;
-       uint32_t rx:1;
-       uint32_t mm:1;
-       uint32_t fa:1;
-       uint32_t rsvd1:19;
-#endif
-
-#define AT_RESERVED    0x00    /* Reserved - attType */
-#define AT_LINK_UP     0x01    /* Link is up */
-#define AT_LINK_DOWN   0x02    /* Link is down */
-
-#ifdef __BIG_ENDIAN_BITFIELD
-       uint8_t granted_AL_PA;
-       uint8_t lipAlPs;
-       uint8_t lipType;
-       uint8_t topology;
-#else  /*  __LITTLE_ENDIAN_BITFIELD */
-       uint8_t topology;
-       uint8_t lipType;
-       uint8_t lipAlPs;
-       uint8_t granted_AL_PA;
-#endif
-
-#define TOPOLOGY_PT_PT 0x01    /* Topology is pt-pt / pt-fabric */
-#define TOPOLOGY_LOOP  0x02    /* Topology is FC-AL */
-#define TOPOLOGY_LNK_MENLO_MAINTENANCE 0x05 /* maint mode zephtr to menlo */
-
-       union {
-               struct ulp_bde lilpBde; /* This BDE points to a 128 byte buffer
-                                          to */
-               /* store the LILP AL_PA position map into */
-               struct ulp_bde64 lilpBde64;
-       } un;
-
-#ifdef __BIG_ENDIAN_BITFIELD
-       uint32_t Dlu:1;
-       uint32_t Dtf:1;
-       uint32_t Drsvd2:14;
-       uint32_t DlnkSpeed:8;
-       uint32_t DnlPort:4;
-       uint32_t Dtx:2;
-       uint32_t Drx:2;
-#else  /*  __LITTLE_ENDIAN_BITFIELD */
-       uint32_t Drx:2;
-       uint32_t Dtx:2;
-       uint32_t DnlPort:4;
-       uint32_t DlnkSpeed:8;
-       uint32_t Drsvd2:14;
-       uint32_t Dtf:1;
-       uint32_t Dlu:1;
-#endif
-
-#ifdef __BIG_ENDIAN_BITFIELD
-       uint32_t Ulu:1;
-       uint32_t Utf:1;
-       uint32_t Ursvd2:14;
-       uint32_t UlnkSpeed:8;
-       uint32_t UnlPort:4;
-       uint32_t Utx:2;
-       uint32_t Urx:2;
-#else  /*  __LITTLE_ENDIAN_BITFIELD */
-       uint32_t Urx:2;
-       uint32_t Utx:2;
-       uint32_t UnlPort:4;
-       uint32_t UlnkSpeed:8;
-       uint32_t Ursvd2:14;
-       uint32_t Utf:1;
-       uint32_t Ulu:1;
-#endif
-
-#define LA_UNKNW_LINK  0x0    /* lnkSpeed */
-#define LA_1GHZ_LINK   0x04   /* lnkSpeed */
-#define LA_2GHZ_LINK   0x08   /* lnkSpeed */
-#define LA_4GHZ_LINK   0x10   /* lnkSpeed */
-#define LA_8GHZ_LINK   0x20   /* lnkSpeed */
-#define LA_10GHZ_LINK  0x40   /* lnkSpeed */
-
-} READ_LA_VAR;
+       uint32_t word2;
+#define lpfc_mbx_read_top_fa_SHIFT             12
+#define lpfc_mbx_read_top_fa_MASK              0x00000001
+#define lpfc_mbx_read_top_fa_WORD              word2
+#define lpfc_mbx_read_top_mm_SHIFT             11
+#define lpfc_mbx_read_top_mm_MASK              0x00000001
+#define lpfc_mbx_read_top_mm_WORD              word2
+#define lpfc_mbx_read_top_pb_SHIFT             9
+#define lpfc_mbx_read_top_pb_MASK              0X00000001
+#define lpfc_mbx_read_top_pb_WORD              word2
+#define lpfc_mbx_read_top_il_SHIFT             8
+#define lpfc_mbx_read_top_il_MASK              0x00000001
+#define lpfc_mbx_read_top_il_WORD              word2
+#define lpfc_mbx_read_top_att_type_SHIFT       0
+#define lpfc_mbx_read_top_att_type_MASK                0x000000FF
+#define lpfc_mbx_read_top_att_type_WORD                word2
+#define LPFC_ATT_RESERVED    0x00      /* Reserved - attType */
+#define LPFC_ATT_LINK_UP     0x01      /* Link is up */
+#define LPFC_ATT_LINK_DOWN   0x02      /* Link is down */
+       uint32_t word3;
+#define lpfc_mbx_read_top_alpa_granted_SHIFT   24
+#define lpfc_mbx_read_top_alpa_granted_MASK    0x000000FF
+#define lpfc_mbx_read_top_alpa_granted_WORD    word3
+#define lpfc_mbx_read_top_lip_alps_SHIFT       16
+#define lpfc_mbx_read_top_lip_alps_MASK                0x000000FF
+#define lpfc_mbx_read_top_lip_alps_WORD                word3
+#define lpfc_mbx_read_top_lip_type_SHIFT       8
+#define lpfc_mbx_read_top_lip_type_MASK                0x000000FF
+#define lpfc_mbx_read_top_lip_type_WORD                word3
+#define lpfc_mbx_read_top_topology_SHIFT       0
+#define lpfc_mbx_read_top_topology_MASK                0x000000FF
+#define lpfc_mbx_read_top_topology_WORD                word3
+#define LPFC_TOPOLOGY_PT_PT 0x01       /* Topology is pt-pt / pt-fabric */
+#define LPFC_TOPOLOGY_LOOP  0x02       /* Topology is FC-AL */
+#define LPFC_TOPOLOGY_MM    0x05       /* maint mode zephtr to menlo */
+       /* store the LILP AL_PA position map into */
+       struct ulp_bde64 lilpBde64;
+#define LPFC_ALPA_MAP_SIZE     128
+       uint32_t word7;
+#define lpfc_mbx_read_top_ld_lu_SHIFT          31
+#define lpfc_mbx_read_top_ld_lu_MASK           0x00000001
+#define lpfc_mbx_read_top_ld_lu_WORD           word7
+#define lpfc_mbx_read_top_ld_tf_SHIFT          30
+#define lpfc_mbx_read_top_ld_tf_MASK           0x00000001
+#define lpfc_mbx_read_top_ld_tf_WORD           word7
+#define lpfc_mbx_read_top_ld_link_spd_SHIFT    8
+#define lpfc_mbx_read_top_ld_link_spd_MASK     0x000000FF
+#define lpfc_mbx_read_top_ld_link_spd_WORD     word7
+#define lpfc_mbx_read_top_ld_nl_port_SHIFT     4
+#define lpfc_mbx_read_top_ld_nl_port_MASK      0x0000000F
+#define lpfc_mbx_read_top_ld_nl_port_WORD      word7
+#define lpfc_mbx_read_top_ld_tx_SHIFT          2
+#define lpfc_mbx_read_top_ld_tx_MASK           0x00000003
+#define lpfc_mbx_read_top_ld_tx_WORD           word7
+#define lpfc_mbx_read_top_ld_rx_SHIFT          0
+#define lpfc_mbx_read_top_ld_rx_MASK           0x00000003
+#define lpfc_mbx_read_top_ld_rx_WORD           word7
+       uint32_t word8;
+#define lpfc_mbx_read_top_lu_SHIFT             31
+#define lpfc_mbx_read_top_lu_MASK              0x00000001
+#define lpfc_mbx_read_top_lu_WORD              word8
+#define lpfc_mbx_read_top_tf_SHIFT             30
+#define lpfc_mbx_read_top_tf_MASK              0x00000001
+#define lpfc_mbx_read_top_tf_WORD              word8
+#define lpfc_mbx_read_top_link_spd_SHIFT       8
+#define lpfc_mbx_read_top_link_spd_MASK                0x000000FF
+#define lpfc_mbx_read_top_link_spd_WORD                word8
+#define lpfc_mbx_read_top_nl_port_SHIFT                4
+#define lpfc_mbx_read_top_nl_port_MASK         0x0000000F
+#define lpfc_mbx_read_top_nl_port_WORD         word8
+#define lpfc_mbx_read_top_tx_SHIFT             2
+#define lpfc_mbx_read_top_tx_MASK              0x00000003
+#define lpfc_mbx_read_top_tx_WORD              word8
+#define lpfc_mbx_read_top_rx_SHIFT             0
+#define lpfc_mbx_read_top_rx_MASK              0x00000003
+#define lpfc_mbx_read_top_rx_WORD              word8
+#define LPFC_LINK_SPEED_UNKNOWN        0x0
+#define LPFC_LINK_SPEED_1GHZ   0x04
+#define LPFC_LINK_SPEED_2GHZ   0x08
+#define LPFC_LINK_SPEED_4GHZ   0x10
+#define LPFC_LINK_SPEED_8GHZ   0x20
+#define LPFC_LINK_SPEED_10GHZ  0x40
+#define LPFC_LINK_SPEED_16GHZ  0x80
+};
 
 /* Structure for MB Command CLEAR_LA (22) */
 
@@ -3016,7 +3030,6 @@ typedef union {
        READ_LNK_VAR varRdLnk;          /* cmd = 18 (READ_LNK_STAT)  */
        REG_LOGIN_VAR varRegLogin;      /* cmd = 19 (REG_LOGIN(64))  */
        UNREG_LOGIN_VAR varUnregLogin;  /* cmd = 20 (UNREG_LOGIN)    */
-       READ_LA_VAR varReadLA;          /* cmd = 21 (READ_LA(64))    */
        CLEAR_LA_VAR varClearLA;        /* cmd = 22 (CLEAR_LA)       */
        DUMP_VAR varDmp;                /* Warm Start DUMP mbx cmd   */
        UNREG_D_ID_VAR varUnregDID;     /* cmd = 0x23 (UNREG_D_ID)   */
@@ -3026,6 +3039,7 @@ typedef union {
        struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ)  */
        struct update_cfg_var varUpdateCfg; /* cmd = 0x1B (UPDATE_CFG)*/
        CONFIG_PORT_VAR varCfgPort;     /* cmd = 0x88 (CONFIG_PORT)  */
+       struct lpfc_mbx_read_top varReadTop; /* cmd = 0x95 (READ_TOPOLOGY) */
        REG_VPI_VAR varRegVpi;          /* cmd = 0x96 (REG_VPI) */
        UNREG_VPI_VAR varUnregVpi;      /* cmd = 0x97 (UNREG_VPI) */
        ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */
index 6e4bc34e1d0d30028f2aaae15e615f5a0d067cd5..94c1aa1136de32e6099b29abad38da59955552da 100644 (file)
@@ -64,29 +64,39 @@ struct lpfc_sli_intf {
 #define lpfc_sli_intf_valid_MASK               0x00000007
 #define lpfc_sli_intf_valid_WORD               word0
 #define LPFC_SLI_INTF_VALID            6
-#define lpfc_sli_intf_featurelevel2_SHIFT      24
-#define lpfc_sli_intf_featurelevel2_MASK       0x0000001F
-#define lpfc_sli_intf_featurelevel2_WORD       word0
-#define lpfc_sli_intf_featurelevel1_SHIFT      16
-#define lpfc_sli_intf_featurelevel1_MASK       0x000000FF
-#define lpfc_sli_intf_featurelevel1_WORD       word0
-#define LPFC_SLI_INTF_FEATURELEVEL1_1  1
-#define LPFC_SLI_INTF_FEATURELEVEL1_2  2
+#define lpfc_sli_intf_sli_hint2_SHIFT          24
+#define lpfc_sli_intf_sli_hint2_MASK           0x0000001F
+#define lpfc_sli_intf_sli_hint2_WORD           word0
+#define LPFC_SLI_INTF_SLI_HINT2_NONE   0
+#define lpfc_sli_intf_sli_hint1_SHIFT          16
+#define lpfc_sli_intf_sli_hint1_MASK           0x000000FF
+#define lpfc_sli_intf_sli_hint1_WORD           word0
+#define LPFC_SLI_INTF_SLI_HINT1_NONE   0
+#define LPFC_SLI_INTF_SLI_HINT1_1      1
+#define LPFC_SLI_INTF_SLI_HINT1_2      2
+#define lpfc_sli_intf_if_type_SHIFT            12
+#define lpfc_sli_intf_if_type_MASK             0x0000000F
+#define lpfc_sli_intf_if_type_WORD             word0
+#define LPFC_SLI_INTF_IF_TYPE_0                0
+#define LPFC_SLI_INTF_IF_TYPE_1                1
+#define LPFC_SLI_INTF_IF_TYPE_2                2
 #define lpfc_sli_intf_sli_family_SHIFT         8
-#define lpfc_sli_intf_sli_family_MASK          0x000000FF
+#define lpfc_sli_intf_sli_family_MASK          0x0000000F
 #define lpfc_sli_intf_sli_family_WORD          word0
-#define LPFC_SLI_INTF_FAMILY_BE2       0
-#define LPFC_SLI_INTF_FAMILY_BE3       1
+#define LPFC_SLI_INTF_FAMILY_BE2       0x0
+#define LPFC_SLI_INTF_FAMILY_BE3       0x1
+#define LPFC_SLI_INTF_FAMILY_LNCR_A0   0xa
+#define LPFC_SLI_INTF_FAMILY_LNCR_B0   0xb
 #define lpfc_sli_intf_slirev_SHIFT             4
 #define lpfc_sli_intf_slirev_MASK              0x0000000F
 #define lpfc_sli_intf_slirev_WORD              word0
 #define LPFC_SLI_INTF_REV_SLI3         3
 #define LPFC_SLI_INTF_REV_SLI4         4
-#define lpfc_sli_intf_if_type_SHIFT            0
-#define lpfc_sli_intf_if_type_MASK             0x00000007
-#define lpfc_sli_intf_if_type_WORD             word0
-#define LPFC_SLI_INTF_IF_TYPE_0                0
-#define LPFC_SLI_INTF_IF_TYPE_1                1
+#define lpfc_sli_intf_func_type_SHIFT          0
+#define lpfc_sli_intf_func_type_MASK           0x00000001
+#define lpfc_sli_intf_func_type_WORD           word0
+#define LPFC_SLI_INTF_IF_TYPE_PHYS     0
+#define LPFC_SLI_INTF_IF_TYPE_VIRT     1
 };
 
 #define LPFC_SLI4_MBX_EMBED    true
@@ -450,35 +460,40 @@ struct lpfc_register {
        uint32_t word0;
 };
 
+/* The following BAR0 Registers apply to SLI4 if_type 0 UCNAs. */
 #define LPFC_UERR_STATUS_HI            0x00A4
 #define LPFC_UERR_STATUS_LO            0x00A0
 #define LPFC_UE_MASK_HI                        0x00AC
 #define LPFC_UE_MASK_LO                        0x00A8
+
+/* The following BAR0 register sets are defined for if_type 0 and 2 UCNAs. */
 #define LPFC_SLI_INTF                  0x0058
 
-/* BAR0 Registers */
-#define LPFC_HST_STATE                 0x00AC
-#define lpfc_hst_state_perr_SHIFT      31
-#define lpfc_hst_state_perr_MASK       0x1
-#define lpfc_hst_state_perr_WORD       word0
-#define lpfc_hst_state_sfi_SHIFT       30
-#define lpfc_hst_state_sfi_MASK                0x1
-#define lpfc_hst_state_sfi_WORD                word0
-#define lpfc_hst_state_nip_SHIFT       29
-#define lpfc_hst_state_nip_MASK                0x1
-#define lpfc_hst_state_nip_WORD                word0
-#define lpfc_hst_state_ipc_SHIFT       28
-#define lpfc_hst_state_ipc_MASK                0x1
-#define lpfc_hst_state_ipc_WORD                word0
-#define lpfc_hst_state_xrom_SHIFT      27
-#define lpfc_hst_state_xrom_MASK       0x1
-#define lpfc_hst_state_xrom_WORD       word0
-#define lpfc_hst_state_dl_SHIFT                26
-#define lpfc_hst_state_dl_MASK         0x1
-#define lpfc_hst_state_dl_WORD         word0
-#define lpfc_hst_state_port_status_SHIFT       0
-#define lpfc_hst_state_port_status_MASK                0xFFFF
-#define lpfc_hst_state_port_status_WORD                word0
+#define LPFC_SLIPORT_IF2_SMPHR         0x0400
+#define lpfc_port_smphr_perr_SHIFT     31
+#define lpfc_port_smphr_perr_MASK      0x1
+#define lpfc_port_smphr_perr_WORD      word0
+#define lpfc_port_smphr_sfi_SHIFT      30
+#define lpfc_port_smphr_sfi_MASK       0x1
+#define lpfc_port_smphr_sfi_WORD       word0
+#define lpfc_port_smphr_nip_SHIFT      29
+#define lpfc_port_smphr_nip_MASK       0x1
+#define lpfc_port_smphr_nip_WORD       word0
+#define lpfc_port_smphr_ipc_SHIFT      28
+#define lpfc_port_smphr_ipc_MASK       0x1
+#define lpfc_port_smphr_ipc_WORD       word0
+#define lpfc_port_smphr_scr1_SHIFT     27
+#define lpfc_port_smphr_scr1_MASK      0x1
+#define lpfc_port_smphr_scr1_WORD      word0
+#define lpfc_port_smphr_scr2_SHIFT     26
+#define lpfc_port_smphr_scr2_MASK      0x1
+#define lpfc_port_smphr_scr2_WORD      word0
+#define lpfc_port_smphr_host_scratch_SHIFT     16
+#define lpfc_port_smphr_host_scratch_MASK      0xFF
+#define lpfc_port_smphr_host_scratch_WORD      word0
+#define lpfc_port_smphr_port_status_SHIFT      0
+#define lpfc_port_smphr_port_status_MASK       0xFFFF
+#define lpfc_port_smphr_port_status_WORD       word0
 
 #define LPFC_POST_STAGE_POWER_ON_RESET                 0x0000
 #define LPFC_POST_STAGE_AWAITING_HOST_RDY              0x0001
@@ -511,10 +526,46 @@ struct lpfc_register {
 #define LPFC_POST_STAGE_RC_DONE                                0x0B07
 #define LPFC_POST_STAGE_REBOOT_SYSTEM                  0x0B08
 #define LPFC_POST_STAGE_MAC_ADDRESS                    0x0C00
-#define LPFC_POST_STAGE_ARMFW_READY                    0xC000
-#define LPFC_POST_STAGE_ARMFW_UE                       0xF000
+#define LPFC_POST_STAGE_PORT_READY                     0xC000
+#define LPFC_POST_STAGE_PORT_UE                        0xF000
+
+#define LPFC_SLIPORT_STATUS            0x0404
+#define lpfc_sliport_status_err_SHIFT  31
+#define lpfc_sliport_status_err_MASK   0x1
+#define lpfc_sliport_status_err_WORD   word0
+#define lpfc_sliport_status_end_SHIFT  30
+#define lpfc_sliport_status_end_MASK   0x1
+#define lpfc_sliport_status_end_WORD   word0
+#define lpfc_sliport_status_oti_SHIFT  29
+#define lpfc_sliport_status_oti_MASK   0x1
+#define lpfc_sliport_status_oti_WORD   word0
+#define lpfc_sliport_status_rn_SHIFT   24
+#define lpfc_sliport_status_rn_MASK    0x1
+#define lpfc_sliport_status_rn_WORD    word0
+#define lpfc_sliport_status_rdy_SHIFT  23
+#define lpfc_sliport_status_rdy_MASK   0x1
+#define lpfc_sliport_status_rdy_WORD   word0
+#define MAX_IF_TYPE_2_RESETS   1000
+
+#define LPFC_SLIPORT_CNTRL             0x0408
+#define lpfc_sliport_ctrl_end_SHIFT    30
+#define lpfc_sliport_ctrl_end_MASK     0x1
+#define lpfc_sliport_ctrl_end_WORD     word0
+#define LPFC_SLIPORT_LITTLE_ENDIAN 0
+#define LPFC_SLIPORT_BIG_ENDIAN           1
+#define lpfc_sliport_ctrl_ip_SHIFT     27
+#define lpfc_sliport_ctrl_ip_MASK      0x1
+#define lpfc_sliport_ctrl_ip_WORD      word0
+#define LPFC_SLIPORT_INIT_PORT 1
+
+#define LPFC_SLIPORT_ERR_1             0x040C
+#define LPFC_SLIPORT_ERR_2             0x0410
+
+/* The following Registers apply to SLI4 if_type 0 UCNAs. They typically
+ * reside in BAR 2.
+ */
+#define LPFC_SLIPORT_IF0_SMPHR 0x00AC
 
-/* BAR1 Registers */
 #define LPFC_IMR_MASK_ALL      0xFFFFFFFF
 #define LPFC_ISCR_CLEAR_ALL    0xFFFFFFFF
 
@@ -569,14 +620,21 @@ struct lpfc_register {
 #define LPFC_SLI4_INTR30               BIT30
 #define LPFC_SLI4_INTR31               BIT31
 
-/* BAR2 Registers */
+/*
+ * The Doorbell registers defined here exist in different BAR
+ * register sets depending on the UCNA Port's reported if_type
+ * value.  For UCNA ports running SLI4 and if_type 0, they reside in
+ * BAR4.  For UCNA ports running SLI4 and if_type 2, they reside in
+ * BAR0.  The offsets are the same so the driver must account for
+ * any base address difference.
+ */
 #define LPFC_RQ_DOORBELL               0x00A0
 #define lpfc_rq_doorbell_num_posted_SHIFT      16
 #define lpfc_rq_doorbell_num_posted_MASK       0x3FFF
 #define lpfc_rq_doorbell_num_posted_WORD       word0
 #define LPFC_RQ_POST_BATCH             8       /* RQEs to post at one time */
 #define lpfc_rq_doorbell_id_SHIFT              0
-#define lpfc_rq_doorbell_id_MASK               0x03FF
+#define lpfc_rq_doorbell_id_MASK               0xFFFF
 #define lpfc_rq_doorbell_id_WORD               word0
 
 #define LPFC_WQ_DOORBELL               0x0040
@@ -591,6 +649,11 @@ struct lpfc_register {
 #define lpfc_wq_doorbell_id_WORD               word0
 
 #define LPFC_EQCQ_DOORBELL             0x0120
+#define lpfc_eqcq_doorbell_se_SHIFT            31
+#define lpfc_eqcq_doorbell_se_MASK             0x0001
+#define lpfc_eqcq_doorbell_se_WORD             word0
+#define LPFC_EQCQ_SOLICIT_ENABLE_OFF   0
+#define LPFC_EQCQ_SOLICIT_ENABLE_ON    1
 #define lpfc_eqcq_doorbell_arm_SHIFT           29
 #define lpfc_eqcq_doorbell_arm_MASK            0x0001
 #define lpfc_eqcq_doorbell_arm_WORD            word0
@@ -628,7 +691,7 @@ struct lpfc_register {
 #define lpfc_mq_doorbell_num_posted_MASK       0x3FFF
 #define lpfc_mq_doorbell_num_posted_WORD       word0
 #define lpfc_mq_doorbell_id_SHIFT              0
-#define lpfc_mq_doorbell_id_MASK               0x03FF
+#define lpfc_mq_doorbell_id_MASK               0xFFFF
 #define lpfc_mq_doorbell_id_WORD               word0
 
 struct lpfc_sli4_cfg_mhdr {
@@ -1048,12 +1111,18 @@ struct lpfc_mbx_mq_create_ext {
 #define lpfc_mbx_mq_create_ext_async_evt_link_SHIFT    LPFC_TRAILER_CODE_LINK
 #define lpfc_mbx_mq_create_ext_async_evt_link_MASK     0x00000001
 #define lpfc_mbx_mq_create_ext_async_evt_link_WORD     async_evt_bmap
-#define lpfc_mbx_mq_create_ext_async_evt_fcfste_SHIFT  LPFC_TRAILER_CODE_FCOE
-#define lpfc_mbx_mq_create_ext_async_evt_fcfste_MASK   0x00000001
-#define lpfc_mbx_mq_create_ext_async_evt_fcfste_WORD   async_evt_bmap
+#define lpfc_mbx_mq_create_ext_async_evt_fip_SHIFT     LPFC_TRAILER_CODE_FCOE
+#define lpfc_mbx_mq_create_ext_async_evt_fip_MASK      0x00000001
+#define lpfc_mbx_mq_create_ext_async_evt_fip_WORD      async_evt_bmap
 #define lpfc_mbx_mq_create_ext_async_evt_group5_SHIFT  LPFC_TRAILER_CODE_GRP5
 #define lpfc_mbx_mq_create_ext_async_evt_group5_MASK   0x00000001
 #define lpfc_mbx_mq_create_ext_async_evt_group5_WORD   async_evt_bmap
+#define lpfc_mbx_mq_create_ext_async_evt_fc_SHIFT      LPFC_TRAILER_CODE_FC
+#define lpfc_mbx_mq_create_ext_async_evt_fc_MASK       0x00000001
+#define lpfc_mbx_mq_create_ext_async_evt_fc_WORD       async_evt_bmap
+#define lpfc_mbx_mq_create_ext_async_evt_sli_SHIFT     LPFC_TRAILER_CODE_SLI
+#define lpfc_mbx_mq_create_ext_async_evt_sli_MASK      0x00000001
+#define lpfc_mbx_mq_create_ext_async_evt_sli_WORD      async_evt_bmap
                        struct mq_context context;
                        struct dma_address page[LPFC_MAX_MQ_PAGE];
                } request;
@@ -1307,7 +1376,7 @@ struct lpfc_mbx_query_fw_cfg {
 #define lpfc_function_mode_dal_WORD            function_mode
 #define lpfc_function_mode_lro_SHIFT           9
 #define lpfc_function_mode_lro_MASK            0x00000001
-#define lpfc_function_mode_lro_WORD            function_mode9
+#define lpfc_function_mode_lro_WORD            function_mode
 #define lpfc_function_mode_flex10_SHIFT                10
 #define lpfc_function_mode_flex10_MASK         0x00000001
 #define lpfc_function_mode_flex10_WORD         function_mode
@@ -1358,10 +1427,16 @@ struct lpfc_mbx_init_vfi {
 #define lpfc_init_vfi_vf_SHIFT         29
 #define lpfc_init_vfi_vf_MASK          0x00000001
 #define lpfc_init_vfi_vf_WORD          word1
+#define lpfc_init_vfi_vp_SHIFT         28
+#define lpfc_init_vfi_vp_MASK          0x00000001
+#define lpfc_init_vfi_vp_WORD          word1
 #define lpfc_init_vfi_vfi_SHIFT                0
 #define lpfc_init_vfi_vfi_MASK         0x0000FFFF
 #define lpfc_init_vfi_vfi_WORD         word1
        uint32_t word2;
+#define lpfc_init_vfi_vpi_SHIFT                16
+#define lpfc_init_vfi_vpi_MASK         0x0000FFFF
+#define lpfc_init_vfi_vpi_WORD         word2
 #define lpfc_init_vfi_fcfi_SHIFT       0
 #define lpfc_init_vfi_fcfi_MASK                0x0000FFFF
 #define lpfc_init_vfi_fcfi_WORD                word2
@@ -2069,6 +2144,8 @@ struct lpfc_mcqe {
 #define LPFC_TRAILER_CODE_FCOE 0x2
 #define LPFC_TRAILER_CODE_DCBX 0x3
 #define LPFC_TRAILER_CODE_GRP5 0x5
+#define LPFC_TRAILER_CODE_FC   0x10
+#define LPFC_TRAILER_CODE_SLI  0x11
 };
 
 struct lpfc_acqe_link {
@@ -2094,11 +2171,12 @@ struct lpfc_acqe_link {
 #define LPFC_ASYNC_LINK_STATUS_UP              0x1
 #define LPFC_ASYNC_LINK_STATUS_LOGICAL_DOWN    0x2
 #define LPFC_ASYNC_LINK_STATUS_LOGICAL_UP      0x3
-#define lpfc_acqe_link_physical_SHIFT          0
-#define lpfc_acqe_link_physical_MASK           0x000000FF
-#define lpfc_acqe_link_physical_WORD           word0
-#define LPFC_ASYNC_LINK_PORT_A                 0x0
-#define LPFC_ASYNC_LINK_PORT_B                 0x1
+#define lpfc_acqe_link_type_SHIFT              6
+#define lpfc_acqe_link_type_MASK               0x00000003
+#define lpfc_acqe_link_type_WORD               word0
+#define lpfc_acqe_link_number_SHIFT            0
+#define lpfc_acqe_link_number_MASK             0x0000003F
+#define lpfc_acqe_link_number_WORD             word0
        uint32_t word1;
 #define lpfc_acqe_link_fault_SHIFT     0
 #define lpfc_acqe_link_fault_MASK      0x000000FF
@@ -2106,29 +2184,31 @@ struct lpfc_acqe_link {
 #define LPFC_ASYNC_LINK_FAULT_NONE     0x0
 #define LPFC_ASYNC_LINK_FAULT_LOCAL    0x1
 #define LPFC_ASYNC_LINK_FAULT_REMOTE   0x2
-#define lpfc_acqe_qos_link_speed_SHIFT 16
-#define lpfc_acqe_qos_link_speed_MASK  0x0000FFFF
-#define lpfc_acqe_qos_link_speed_WORD  word1
+#define lpfc_acqe_logical_link_speed_SHIFT     16
+#define lpfc_acqe_logical_link_speed_MASK      0x0000FFFF
+#define lpfc_acqe_logical_link_speed_WORD      word1
        uint32_t event_tag;
        uint32_t trailer;
+#define LPFC_LINK_EVENT_TYPE_PHYSICAL  0x0
+#define LPFC_LINK_EVENT_TYPE_VIRTUAL   0x1
 };
 
-struct lpfc_acqe_fcoe {
+struct lpfc_acqe_fip {
        uint32_t index;
        uint32_t word1;
-#define lpfc_acqe_fcoe_fcf_count_SHIFT         0
-#define lpfc_acqe_fcoe_fcf_count_MASK          0x0000FFFF
-#define lpfc_acqe_fcoe_fcf_count_WORD          word1
-#define lpfc_acqe_fcoe_event_type_SHIFT                16
-#define lpfc_acqe_fcoe_event_type_MASK         0x0000FFFF
-#define lpfc_acqe_fcoe_event_type_WORD         word1
-#define LPFC_FCOE_EVENT_TYPE_NEW_FCF           0x1
-#define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL    0x2
-#define LPFC_FCOE_EVENT_TYPE_FCF_DEAD          0x3
-#define LPFC_FCOE_EVENT_TYPE_CVL               0x4
-#define LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD     0x5
+#define lpfc_acqe_fip_fcf_count_SHIFT          0
+#define lpfc_acqe_fip_fcf_count_MASK           0x0000FFFF
+#define lpfc_acqe_fip_fcf_count_WORD           word1
+#define lpfc_acqe_fip_event_type_SHIFT         16
+#define lpfc_acqe_fip_event_type_MASK          0x0000FFFF
+#define lpfc_acqe_fip_event_type_WORD          word1
        uint32_t event_tag;
        uint32_t trailer;
+#define LPFC_FIP_EVENT_TYPE_NEW_FCF            0x1
+#define LPFC_FIP_EVENT_TYPE_FCF_TABLE_FULL     0x2
+#define LPFC_FIP_EVENT_TYPE_FCF_DEAD           0x3
+#define LPFC_FIP_EVENT_TYPE_CVL                        0x4
+#define LPFC_FIP_EVENT_TYPE_FCF_PARAM_MOD      0x5
 };
 
 struct lpfc_acqe_dcbx {
@@ -2140,9 +2220,12 @@ struct lpfc_acqe_dcbx {
 
 struct lpfc_acqe_grp5 {
        uint32_t word0;
-#define lpfc_acqe_grp5_pport_SHIFT     0
-#define lpfc_acqe_grp5_pport_MASK      0x000000FF
-#define lpfc_acqe_grp5_pport_WORD      word0
+#define lpfc_acqe_grp5_type_SHIFT              6
+#define lpfc_acqe_grp5_type_MASK               0x00000003
+#define lpfc_acqe_grp5_type_WORD               word0
+#define lpfc_acqe_grp5_number_SHIFT            0
+#define lpfc_acqe_grp5_number_MASK             0x0000003F
+#define lpfc_acqe_grp5_number_WORD             word0
        uint32_t word1;
 #define lpfc_acqe_grp5_llink_spd_SHIFT 16
 #define lpfc_acqe_grp5_llink_spd_MASK  0x0000FFFF
@@ -2151,6 +2234,68 @@ struct lpfc_acqe_grp5 {
        uint32_t trailer;
 };
 
+struct lpfc_acqe_fc_la {
+       uint32_t word0;
+#define lpfc_acqe_fc_la_speed_SHIFT            24
+#define lpfc_acqe_fc_la_speed_MASK             0x000000FF
+#define lpfc_acqe_fc_la_speed_WORD             word0
+#define LPFC_FC_LA_SPEED_UNKOWN                0x0
+#define LPFC_FC_LA_SPEED_1G            0x1
+#define LPFC_FC_LA_SPEED_2G            0x2
+#define LPFC_FC_LA_SPEED_4G            0x4
+#define LPFC_FC_LA_SPEED_8G            0x8
+#define LPFC_FC_LA_SPEED_10G           0xA
+#define LPFC_FC_LA_SPEED_16G           0x10
+#define lpfc_acqe_fc_la_topology_SHIFT         16
+#define lpfc_acqe_fc_la_topology_MASK          0x000000FF
+#define lpfc_acqe_fc_la_topology_WORD          word0
+#define LPFC_FC_LA_TOP_UNKOWN          0x0
+#define LPFC_FC_LA_TOP_P2P             0x1
+#define LPFC_FC_LA_TOP_FCAL            0x2
+#define LPFC_FC_LA_TOP_INTERNAL_LOOP   0x3
+#define LPFC_FC_LA_TOP_SERDES_LOOP     0x4
+#define lpfc_acqe_fc_la_att_type_SHIFT         8
+#define lpfc_acqe_fc_la_att_type_MASK          0x000000FF
+#define lpfc_acqe_fc_la_att_type_WORD          word0
+#define LPFC_FC_LA_TYPE_LINK_UP                0x1
+#define LPFC_FC_LA_TYPE_LINK_DOWN      0x2
+#define LPFC_FC_LA_TYPE_NO_HARD_ALPA   0x3
+#define lpfc_acqe_fc_la_port_type_SHIFT                6
+#define lpfc_acqe_fc_la_port_type_MASK         0x00000003
+#define lpfc_acqe_fc_la_port_type_WORD         word0
+#define LPFC_LINK_TYPE_ETHERNET                0x0
+#define LPFC_LINK_TYPE_FC              0x1
+#define lpfc_acqe_fc_la_port_number_SHIFT      0
+#define lpfc_acqe_fc_la_port_number_MASK       0x0000003F
+#define lpfc_acqe_fc_la_port_number_WORD       word0
+       uint32_t word1;
+#define lpfc_acqe_fc_la_llink_spd_SHIFT                16
+#define lpfc_acqe_fc_la_llink_spd_MASK         0x0000FFFF
+#define lpfc_acqe_fc_la_llink_spd_WORD         word1
+#define lpfc_acqe_fc_la_fault_SHIFT            0
+#define lpfc_acqe_fc_la_fault_MASK             0x000000FF
+#define lpfc_acqe_fc_la_fault_WORD             word1
+#define LPFC_FC_LA_FAULT_NONE          0x0
+#define LPFC_FC_LA_FAULT_LOCAL         0x1
+#define LPFC_FC_LA_FAULT_REMOTE                0x2
+       uint32_t event_tag;
+       uint32_t trailer;
+#define LPFC_FC_LA_EVENT_TYPE_FC_LINK          0x1
+#define LPFC_FC_LA_EVENT_TYPE_SHARED_LINK      0x2
+};
+
+struct lpfc_acqe_sli {
+       uint32_t event_data1;
+       uint32_t event_data2;
+       uint32_t reserved;
+       uint32_t trailer;
+#define LPFC_SLI_EVENT_TYPE_PORT_ERROR         0x1
+#define LPFC_SLI_EVENT_TYPE_OVER_TEMP          0x2
+#define LPFC_SLI_EVENT_TYPE_NORM_TEMP          0x3
+#define LPFC_SLI_EVENT_TYPE_NVLOG_POST         0x4
+#define LPFC_SLI_EVENT_TYPE_DIAG_DUMP          0x5
+};
+
 /*
  * Define the bootstrap mailbox (bmbx) region used to communicate
  * mailbox command between the host and port. The mailbox consists
@@ -2210,7 +2355,7 @@ struct wqe_common {
 #define wqe_rcvoxid_WORD      word9
        uint32_t word10;
 #define wqe_ebde_cnt_SHIFT    0
-#define wqe_ebde_cnt_MASK     0x00000007
+#define wqe_ebde_cnt_MASK     0x0000000f
 #define wqe_ebde_cnt_WORD     word10
 #define wqe_lenloc_SHIFT      7
 #define wqe_lenloc_MASK       0x00000003
@@ -2402,7 +2547,6 @@ struct xmit_seq64_wqe {
        uint32_t relative_offset;
        struct wqe_rctl_dfctl wge_ctl;
        struct wqe_common wqe_com; /* words 6-11 */
-       /* Note: word10 different REVISIT */
        uint32_t xmit_len;
        uint32_t rsvd_12_15[3];
 };
index b3065791f30333b9667dcb0f9d3d222facb76fc0..462242dcdd0a1c4ced603622c1839bd97e70d246 100644 (file)
@@ -446,23 +446,25 @@ lpfc_config_port_post(struct lpfc_hba *phba)
        /* Get the default values for Model Name and Description */
        lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);
 
-       if ((phba->cfg_link_speed > LINK_SPEED_10G)
-           || ((phba->cfg_link_speed == LINK_SPEED_1G)
+       if ((phba->cfg_link_speed > LPFC_USER_LINK_SPEED_16G)
+           || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_1G)
                && !(phba->lmt & LMT_1Gb))
-           || ((phba->cfg_link_speed == LINK_SPEED_2G)
+           || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_2G)
                && !(phba->lmt & LMT_2Gb))
-           || ((phba->cfg_link_speed == LINK_SPEED_4G)
+           || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_4G)
                && !(phba->lmt & LMT_4Gb))
-           || ((phba->cfg_link_speed == LINK_SPEED_8G)
+           || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_8G)
                && !(phba->lmt & LMT_8Gb))
-           || ((phba->cfg_link_speed == LINK_SPEED_10G)
-               && !(phba->lmt & LMT_10Gb))) {
+           || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_10G)
+               && !(phba->lmt & LMT_10Gb))
+           || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G)
+               && !(phba->lmt & LMT_16Gb))) {
                /* Reset link speed to auto */
                lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT,
                        "1302 Invalid speed for this board: "
                        "Reset link speed to auto: x%x\n",
                        phba->cfg_link_speed);
-                       phba->cfg_link_speed = LINK_SPEED_AUTO;
+                       phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
        }
 
        phba->link_state = LPFC_LINK_DOWN;
@@ -648,22 +650,23 @@ lpfc_hba_init_link(struct lpfc_hba *phba, uint32_t flag)
        mb = &pmb->u.mb;
        pmb->vport = vport;
 
-       lpfc_init_link(phba, pmb, phba->cfg_topology,
-               phba->cfg_link_speed);
+       lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
        pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
        lpfc_set_loopback_flag(phba);
        rc = lpfc_sli_issue_mbox(phba, pmb, flag);
-       if (rc != MBX_SUCCESS) {
+       if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                        "0498 Adapter failed to init, mbxCmd x%x "
                        "INIT_LINK, mbxStatus x%x\n",
                        mb->mbxCommand, mb->mbxStatus);
-               /* Clear all interrupt enable conditions */
-               writel(0, phba->HCregaddr);
-               readl(phba->HCregaddr); /* flush */
-               /* Clear all pending interrupts */
-               writel(0xffffffff, phba->HAregaddr);
-               readl(phba->HAregaddr); /* flush */
+               if (phba->sli_rev <= LPFC_SLI_REV3) {
+                       /* Clear all interrupt enable conditions */
+                       writel(0, phba->HCregaddr);
+                       readl(phba->HCregaddr); /* flush */
+                       /* Clear all pending interrupts */
+                       writel(0xffffffff, phba->HAregaddr);
+                       readl(phba->HAregaddr); /* flush */
+               }
                phba->link_state = LPFC_HBA_ERROR;
                if (rc != MBX_BUSY || flag == MBX_POLL)
                        mempool_free(pmb, phba->mbox_mem_pool);
@@ -926,6 +929,35 @@ lpfc_hb_timeout(unsigned long ptr)
        return;
 }
 
+/**
+ * lpfc_rrq_timeout - The RRQ-timer timeout handler
+ * @ptr: unsigned long holds the pointer to lpfc hba data structure.
+ *
+ * This is the RRQ-timer timeout handler registered to the lpfc driver. When
+ * this timer fires, a RRQ timeout event shall be posted to the lpfc driver
+ * work-port-events bitmap and the worker thread is notified. This timeout
+ * event will be used by the worker thread to invoke the actual timeout
+ * handler routine, lpfc_rrq_handler. Any periodical operations will
+ * be performed in the timeout handler and the RRQ timeout event bit shall
+ * be cleared by the worker thread after it has taken the event bitmap out.
+ **/
+static void
+lpfc_rrq_timeout(unsigned long ptr)
+{
+       struct lpfc_hba *phba;
+       uint32_t tmo_posted;
+       unsigned long iflag;
+
+       phba = (struct lpfc_hba *)ptr;
+       spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
+       tmo_posted = phba->hba_flag & HBA_RRQ_ACTIVE;
+       if (!tmo_posted)
+               phba->hba_flag |= HBA_RRQ_ACTIVE;
+       spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
+       if (!tmo_posted)
+               lpfc_worker_wake_up(phba);
+}
+
 /**
  * lpfc_hb_mbox_cmpl - The lpfc heart-beat mailbox command callback function
  * @phba: pointer to lpfc hba data structure.
@@ -1374,6 +1406,8 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
        struct lpfc_vport *vport = phba->pport;
        uint32_t event_data;
        struct Scsi_Host *shost;
+       uint32_t if_type;
+       struct lpfc_register portstat_reg;
 
        /* If the pci channel is offline, ignore possible errors, since
         * we cannot communicate with the pci card anyway.
@@ -1390,17 +1424,49 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
        /* For now, the actual action for SLI4 device handling is not
         * specified yet, just treated it as adaptor hardware failure
         */
-       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                       "0143 SLI4 Adapter Hardware Error Data: x%x x%x\n",
-                       phba->work_status[0], phba->work_status[1]);
-
        event_data = FC_REG_DUMP_EVENT;
        shost = lpfc_shost_from_vport(vport);
        fc_host_post_vendor_event(shost, fc_get_event_number(),
                                  sizeof(event_data), (char *) &event_data,
                                  SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
 
-       lpfc_sli4_offline_eratt(phba);
+       if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+       switch (if_type) {
+       case LPFC_SLI_INTF_IF_TYPE_0:
+               lpfc_sli4_offline_eratt(phba);
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_2:
+               portstat_reg.word0 =
+                       readl(phba->sli4_hba.u.if_type2.STATUSregaddr);
+
+               if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) {
+                       /* TODO: Register for Overtemp async events. */
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "2889 Port Overtemperature event, "
+                               "taking port\n");
+                       spin_lock_irq(&phba->hbalock);
+                       phba->over_temp_state = HBA_OVER_TEMP;
+                       spin_unlock_irq(&phba->hbalock);
+                       lpfc_sli4_offline_eratt(phba);
+                       return;
+               }
+               if (bf_get(lpfc_sliport_status_rn, &portstat_reg)) {
+                       /*
+                        * TODO: Attempt port recovery via a port reset.
+                        * When fully implemented, the driver should
+                        * attempt to recover the port here and return.
+                        * For now, log an error and take the port offline.
+                        */
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "2887 Port Error: Attempting "
+                                       "Port Recovery\n");
+               }
+               lpfc_sli4_offline_eratt(phba);
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_1:
+       default:
+               break;
+       }
 }
 
 /**
@@ -1459,8 +1525,8 @@ lpfc_handle_latt(struct lpfc_hba *phba)
        lpfc_els_flush_all_cmd(phba);
 
        psli->slistat.link_event++;
-       lpfc_read_la(phba, pmb, mp);
-       pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la;
+       lpfc_read_topology(phba, pmb, mp);
+       pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
        pmb->vport = vport;
        /* Block ELS IOCBs until we have processed this mbox command */
        phba->sli.ring[LPFC_ELS_RING].flag |= LPFC_STOP_IOCB_EVENT;
@@ -1853,6 +1919,14 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
                m = (typeof(m)){"LPVe12002", "PCIe Shared I/O",
                                "Fibre Channel Adapter"};
                break;
+       case PCI_DEVICE_ID_LANCER_FC:
+               oneConnect = 1;
+               m = (typeof(m)){"Undefined", "PCIe", "Fibre Channel Adapter"};
+               break;
+       case PCI_DEVICE_ID_LANCER_FCOE:
+               oneConnect = 1;
+               m = (typeof(m)){"Undefined", "PCIe", "FCoE"};
+               break;
        default:
                m = (typeof(m)){"Unknown", "", ""};
                break;
@@ -2942,63 +3016,6 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
        lpfc_worker_wake_up(phba);
 }
 
-/**
- * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support
- * @phba: pointer to lpfc hba data structure.
- *
- * This function uses the QUERY_FW_CFG mailbox command to determine if the
- * firmware loaded supports FCoE. A return of zero indicates that the mailbox
- * was successful and the firmware supports FCoE. Any other return indicates
- * a error. It is assumed that this function will be called before interrupts
- * are enabled.
- **/
-static int
-lpfc_sli4_fw_cfg_check(struct lpfc_hba *phba)
-{
-       int rc = 0;
-       LPFC_MBOXQ_t *mboxq;
-       struct lpfc_mbx_query_fw_cfg *query_fw_cfg;
-       uint32_t length;
-       uint32_t shdr_status, shdr_add_status;
-
-       mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-       if (!mboxq) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "2621 Failed to allocate mbox for "
-                               "query firmware config cmd\n");
-               return -ENOMEM;
-       }
-       query_fw_cfg = &mboxq->u.mqe.un.query_fw_cfg;
-       length = (sizeof(struct lpfc_mbx_query_fw_cfg) -
-                 sizeof(struct lpfc_sli4_cfg_mhdr));
-       lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
-                        LPFC_MBOX_OPCODE_QUERY_FW_CFG,
-                        length, LPFC_SLI4_MBX_EMBED);
-       rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
-       /* The IOCTL status is embedded in the mailbox subheader. */
-       shdr_status = bf_get(lpfc_mbox_hdr_status,
-                            &query_fw_cfg->header.cfg_shdr.response);
-       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
-                                &query_fw_cfg->header.cfg_shdr.response);
-       if (shdr_status || shdr_add_status || rc != MBX_SUCCESS) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-                               "2622 Query Firmware Config failed "
-                               "mbx status x%x, status x%x add_status x%x\n",
-                               rc, shdr_status, shdr_add_status);
-               return -EINVAL;
-       }
-       if (!bf_get(lpfc_function_mode_fcoe_i, query_fw_cfg)) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-                               "2623 FCoE Function not supported by firmware. "
-                               "Function mode = %08x\n",
-                               query_fw_cfg->function_mode);
-               return -EINVAL;
-       }
-       if (rc != MBX_TIMEOUT)
-               mempool_free(mboxq, phba->mbox_mem_pool);
-       return 0;
-}
-
 /**
  * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code
  * @phba: pointer to lpfc hba data structure.
@@ -3051,20 +3068,20 @@ lpfc_sli4_parse_latt_type(struct lpfc_hba *phba,
        switch (bf_get(lpfc_acqe_link_status, acqe_link)) {
        case LPFC_ASYNC_LINK_STATUS_DOWN:
        case LPFC_ASYNC_LINK_STATUS_LOGICAL_DOWN:
-               att_type = AT_LINK_DOWN;
+               att_type = LPFC_ATT_LINK_DOWN;
                break;
        case LPFC_ASYNC_LINK_STATUS_UP:
                /* Ignore physical link up events - wait for logical link up */
-               att_type = AT_RESERVED;
+               att_type = LPFC_ATT_RESERVED;
                break;
        case LPFC_ASYNC_LINK_STATUS_LOGICAL_UP:
-               att_type = AT_LINK_UP;
+               att_type = LPFC_ATT_LINK_UP;
                break;
        default:
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                                "0399 Invalid link attention type: x%x\n",
                                bf_get(lpfc_acqe_link_status, acqe_link));
-               att_type = AT_RESERVED;
+               att_type = LPFC_ATT_RESERVED;
                break;
        }
        return att_type;
@@ -3088,36 +3105,32 @@ lpfc_sli4_parse_latt_link_speed(struct lpfc_hba *phba,
 
        switch (bf_get(lpfc_acqe_link_speed, acqe_link)) {
        case LPFC_ASYNC_LINK_SPEED_ZERO:
-               link_speed = LA_UNKNW_LINK;
-               break;
        case LPFC_ASYNC_LINK_SPEED_10MBPS:
-               link_speed = LA_UNKNW_LINK;
-               break;
        case LPFC_ASYNC_LINK_SPEED_100MBPS:
-               link_speed = LA_UNKNW_LINK;
+               link_speed = LPFC_LINK_SPEED_UNKNOWN;
                break;
        case LPFC_ASYNC_LINK_SPEED_1GBPS:
-               link_speed = LA_1GHZ_LINK;
+               link_speed = LPFC_LINK_SPEED_1GHZ;
                break;
        case LPFC_ASYNC_LINK_SPEED_10GBPS:
-               link_speed = LA_10GHZ_LINK;
+               link_speed = LPFC_LINK_SPEED_10GHZ;
                break;
        default:
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                                "0483 Invalid link-attention link speed: x%x\n",
                                bf_get(lpfc_acqe_link_speed, acqe_link));
-               link_speed = LA_UNKNW_LINK;
+               link_speed = LPFC_LINK_SPEED_UNKNOWN;
                break;
        }
        return link_speed;
 }
 
 /**
- * lpfc_sli4_async_link_evt - Process the asynchronous link event
+ * lpfc_sli4_async_link_evt - Process the asynchronous FCoE link event
  * @phba: pointer to lpfc hba data structure.
  * @acqe_link: pointer to the async link completion queue entry.
  *
- * This routine is to handle the SLI4 asynchronous link event.
+ * This routine is to handle the SLI4 asynchronous FCoE link event.
  **/
 static void
 lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
@@ -3126,11 +3139,12 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
        struct lpfc_dmabuf *mp;
        LPFC_MBOXQ_t *pmb;
        MAILBOX_t *mb;
-       READ_LA_VAR *la;
+       struct lpfc_mbx_read_top *la;
        uint8_t att_type;
+       int rc;
 
        att_type = lpfc_sli4_parse_latt_type(phba, acqe_link);
-       if (att_type != AT_LINK_DOWN && att_type != AT_LINK_UP)
+       if (att_type != LPFC_ATT_LINK_DOWN && att_type != LPFC_ATT_LINK_UP)
                return;
        phba->fcoe_eventtag = acqe_link->event_tag;
        pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -3161,45 +3175,168 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
        /* Update link event statistics */
        phba->sli.slistat.link_event++;
 
-       /* Create pseudo lpfc_handle_latt mailbox command from link ACQE */
-       lpfc_read_la(phba, pmb, mp);
+       /* Create lpfc_handle_latt mailbox command from link ACQE */
+       lpfc_read_topology(phba, pmb, mp);
+       pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
        pmb->vport = phba->pport;
 
+       /* Keep the link status for extra SLI4 state machine reference */
+       phba->sli4_hba.link_state.speed =
+                               bf_get(lpfc_acqe_link_speed, acqe_link);
+       phba->sli4_hba.link_state.duplex =
+                               bf_get(lpfc_acqe_link_duplex, acqe_link);
+       phba->sli4_hba.link_state.status =
+                               bf_get(lpfc_acqe_link_status, acqe_link);
+       phba->sli4_hba.link_state.type =
+                               bf_get(lpfc_acqe_link_type, acqe_link);
+       phba->sli4_hba.link_state.number =
+                               bf_get(lpfc_acqe_link_number, acqe_link);
+       phba->sli4_hba.link_state.fault =
+                               bf_get(lpfc_acqe_link_fault, acqe_link);
+       phba->sli4_hba.link_state.logical_speed =
+                       bf_get(lpfc_acqe_logical_link_speed, acqe_link);
+       lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+                       "2900 Async FCoE Link event - Speed:%dGBit duplex:x%x "
+                       "LA Type:x%x Port Type:%d Port Number:%d Logical "
+                       "speed:%dMbps Fault:%d\n",
+                       phba->sli4_hba.link_state.speed,
+                       phba->sli4_hba.link_state.topology,
+                       phba->sli4_hba.link_state.status,
+                       phba->sli4_hba.link_state.type,
+                       phba->sli4_hba.link_state.number,
+                       phba->sli4_hba.link_state.logical_speed * 10,
+                       phba->sli4_hba.link_state.fault);
+       /*
+        * For FC Mode: issue the READ_TOPOLOGY mailbox command to fetch
+        * topology info. Note: Optional for non FC-AL ports.
+        */
+       if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+               rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+               if (rc == MBX_NOT_FINISHED)
+                       goto out_free_dmabuf;
+               return;
+       }
+       /*
+        * For FCoE Mode: fill in all the topology information we need and call
+        * the READ_TOPOLOGY completion routine to continue without actually
+        * sending the READ_TOPOLOGY mailbox command to the port.
+        */
        /* Parse and translate status field */
        mb = &pmb->u.mb;
        mb->mbxStatus = lpfc_sli4_parse_latt_fault(phba, acqe_link);
 
        /* Parse and translate link attention fields */
-       la = (READ_LA_VAR *) &pmb->u.mb.un.varReadLA;
+       la = (struct lpfc_mbx_read_top *) &pmb->u.mb.un.varReadTop;
        la->eventTag = acqe_link->event_tag;
-       la->attType = att_type;
-       la->UlnkSpeed = lpfc_sli4_parse_latt_link_speed(phba, acqe_link);
+       bf_set(lpfc_mbx_read_top_att_type, la, att_type);
+       bf_set(lpfc_mbx_read_top_link_spd, la,
+              lpfc_sli4_parse_latt_link_speed(phba, acqe_link));
 
        /* Fake the the following irrelvant fields */
-       la->topology = TOPOLOGY_PT_PT;
-       la->granted_AL_PA = 0;
-       la->il = 0;
-       la->pb = 0;
-       la->fa = 0;
-       la->mm = 0;
+       bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT);
+       bf_set(lpfc_mbx_read_top_alpa_granted, la, 0);
+       bf_set(lpfc_mbx_read_top_il, la, 0);
+       bf_set(lpfc_mbx_read_top_pb, la, 0);
+       bf_set(lpfc_mbx_read_top_fa, la, 0);
+       bf_set(lpfc_mbx_read_top_mm, la, 0);
+
+       /* Invoke the lpfc_handle_latt mailbox command callback function */
+       lpfc_mbx_cmpl_read_topology(phba, pmb);
+
+       return;
 
+out_free_dmabuf:
+       kfree(mp);
+out_free_pmb:
+       mempool_free(pmb, phba->mbox_mem_pool);
+}
+
+/**
+ * lpfc_sli4_async_fc_evt - Process the asynchronous FC link event
+ * @phba: pointer to lpfc hba data structure.
+ * @acqe_fc: pointer to the async fc completion queue entry.
+ *
+ * This routine is to handle the SLI4 asynchronous FC event. It will simply log
+ * that the event was received and then issue a read_topology mailbox command so
+ * that the rest of the driver will treat it the same as SLI3.
+ **/
+static void
+lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
+{
+       struct lpfc_dmabuf *mp;
+       LPFC_MBOXQ_t *pmb;
+       int rc;
+
+       if (bf_get(lpfc_trailer_type, acqe_fc) !=
+           LPFC_FC_LA_EVENT_TYPE_FC_LINK) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                               "2895 Non FC link Event detected.(%d)\n",
+                               bf_get(lpfc_trailer_type, acqe_fc));
+               return;
+       }
        /* Keep the link status for extra SLI4 state machine reference */
        phba->sli4_hba.link_state.speed =
-                               bf_get(lpfc_acqe_link_speed, acqe_link);
-       phba->sli4_hba.link_state.duplex =
-                               bf_get(lpfc_acqe_link_duplex, acqe_link);
+                               bf_get(lpfc_acqe_fc_la_speed, acqe_fc);
+       phba->sli4_hba.link_state.duplex = LPFC_ASYNC_LINK_DUPLEX_FULL;
+       phba->sli4_hba.link_state.topology =
+                               bf_get(lpfc_acqe_fc_la_topology, acqe_fc);
        phba->sli4_hba.link_state.status =
-                               bf_get(lpfc_acqe_link_status, acqe_link);
-       phba->sli4_hba.link_state.physical =
-                               bf_get(lpfc_acqe_link_physical, acqe_link);
+                               bf_get(lpfc_acqe_fc_la_att_type, acqe_fc);
+       phba->sli4_hba.link_state.type =
+                               bf_get(lpfc_acqe_fc_la_port_type, acqe_fc);
+       phba->sli4_hba.link_state.number =
+                               bf_get(lpfc_acqe_fc_la_port_number, acqe_fc);
        phba->sli4_hba.link_state.fault =
-                               bf_get(lpfc_acqe_link_fault, acqe_link);
+                               bf_get(lpfc_acqe_link_fault, acqe_fc);
        phba->sli4_hba.link_state.logical_speed =
-                               bf_get(lpfc_acqe_qos_link_speed, acqe_link);
+                               bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc);
+       lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+                       "2896 Async FC event - Speed:%dGBaud Topology:x%x "
+                       "LA Type:x%x Port Type:%d Port Number:%d Logical speed:"
+                       "%dMbps Fault:%d\n",
+                       phba->sli4_hba.link_state.speed,
+                       phba->sli4_hba.link_state.topology,
+                       phba->sli4_hba.link_state.status,
+                       phba->sli4_hba.link_state.type,
+                       phba->sli4_hba.link_state.number,
+                       phba->sli4_hba.link_state.logical_speed * 10,
+                       phba->sli4_hba.link_state.fault);
+       pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!pmb) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                               "2897 The mboxq allocation failed\n");
+               return;
+       }
+       mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+       if (!mp) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                               "2898 The lpfc_dmabuf allocation failed\n");
+               goto out_free_pmb;
+       }
+       mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
+       if (!mp->virt) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                               "2899 The mbuf allocation failed\n");
+               goto out_free_dmabuf;
+       }
 
-       /* Invoke the lpfc_handle_latt mailbox command callback function */
-       lpfc_mbx_cmpl_read_la(phba, pmb);
+       /* Cleanup any outstanding ELS commands */
+       lpfc_els_flush_all_cmd(phba);
+
+       /* Block ELS IOCBs until we have done process link event */
+       phba->sli.ring[LPFC_ELS_RING].flag |= LPFC_STOP_IOCB_EVENT;
+
+       /* Update link event statistics */
+       phba->sli.slistat.link_event++;
+
+       /* Create lpfc_handle_latt mailbox command from link ACQE */
+       lpfc_read_topology(phba, pmb, mp);
+       pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
+       pmb->vport = phba->pport;
 
+       rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+       if (rc == MBX_NOT_FINISHED)
+               goto out_free_dmabuf;
        return;
 
 out_free_dmabuf:
@@ -3208,6 +3345,24 @@ out_free_pmb:
        mempool_free(pmb, phba->mbox_mem_pool);
 }
 
+/**
+ * lpfc_sli4_async_sli_evt - Process the asynchronous SLI link event
+ * @phba: pointer to lpfc hba data structure.
+ * @acqe_fc: pointer to the async SLI completion queue entry.
+ *
+ * This routine is to handle the SLI4 asynchronous SLI events.
+ **/
+static void
+lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
+{
+       lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+                       "2901 Async SLI event - Event Data1:x%08x Event Data2:"
+                       "x%08x SLI Event Type:%d",
+                       acqe_sli->event_data1, acqe_sli->event_data2,
+                       bf_get(lpfc_trailer_type, acqe_sli));
+       return;
+}
+
 /**
  * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport
  * @vport: pointer to vport data structure.
@@ -3247,10 +3402,12 @@ lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
                if (!ndlp)
                        return 0;
        }
-       if (phba->pport->port_state < LPFC_FLOGI)
+       if ((phba->pport->port_state < LPFC_FLOGI) &&
+               (phba->pport->port_state != LPFC_VPORT_FAILED))
                return NULL;
        /* If virtual link is not yet instantiated ignore CVL */
-       if ((vport != phba->pport) && (vport->port_state < LPFC_FDISC))
+       if ((vport != phba->pport) && (vport->port_state < LPFC_FDISC)
+               && (vport->port_state != LPFC_VPORT_FAILED))
                return NULL;
        shost = lpfc_shost_from_vport(vport);
        if (!shost)
@@ -3285,17 +3442,17 @@ lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
 }
 
 /**
- * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event
+ * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event
  * @phba: pointer to lpfc hba data structure.
  * @acqe_link: pointer to the async fcoe completion queue entry.
  *
  * This routine is to handle the SLI4 asynchronous fcoe event.
  **/
 static void
-lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
-                        struct lpfc_acqe_fcoe *acqe_fcoe)
+lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
+                       struct lpfc_acqe_fip *acqe_fip)
 {
-       uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
+       uint8_t event_type = bf_get(lpfc_trailer_type, acqe_fip);
        int rc;
        struct lpfc_vport *vport;
        struct lpfc_nodelist *ndlp;
@@ -3304,25 +3461,25 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
        struct lpfc_vport **vports;
        int i;
 
-       phba->fc_eventTag = acqe_fcoe->event_tag;
-       phba->fcoe_eventtag = acqe_fcoe->event_tag;
+       phba->fc_eventTag = acqe_fip->event_tag;
+       phba->fcoe_eventtag = acqe_fip->event_tag;
        switch (event_type) {
-       case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
-       case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD:
-               if (event_type == LPFC_FCOE_EVENT_TYPE_NEW_FCF)
+       case LPFC_FIP_EVENT_TYPE_NEW_FCF:
+       case LPFC_FIP_EVENT_TYPE_FCF_PARAM_MOD:
+               if (event_type == LPFC_FIP_EVENT_TYPE_NEW_FCF)
                        lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
                                        LOG_DISCOVERY,
                                        "2546 New FCF event, evt_tag:x%x, "
                                        "index:x%x\n",
-                                       acqe_fcoe->event_tag,
-                                       acqe_fcoe->index);
+                                       acqe_fip->event_tag,
+                                       acqe_fip->index);
                else
                        lpfc_printf_log(phba, KERN_WARNING, LOG_FIP |
                                        LOG_DISCOVERY,
                                        "2788 FCF param modified event, "
                                        "evt_tag:x%x, index:x%x\n",
-                                       acqe_fcoe->event_tag,
-                                       acqe_fcoe->index);
+                                       acqe_fip->event_tag,
+                                       acqe_fip->index);
                if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
                        /*
                         * During period of FCF discovery, read the FCF
@@ -3333,8 +3490,8 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                                        LOG_DISCOVERY,
                                        "2779 Read FCF (x%x) for updating "
                                        "roundrobin FCF failover bmask\n",
-                                       acqe_fcoe->index);
-                       rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
+                                       acqe_fip->index);
+                       rc = lpfc_sli4_read_fcf_rec(phba, acqe_fip->index);
                }
 
                /* If the FCF discovery is in progress, do nothing. */
@@ -3360,7 +3517,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
                                "2770 Start FCF table scan per async FCF "
                                "event, evt_tag:x%x, index:x%x\n",
-                               acqe_fcoe->event_tag, acqe_fcoe->index);
+                               acqe_fip->event_tag, acqe_fip->index);
                rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
                                                     LPFC_FCOE_FCF_GET_FIRST);
                if (rc)
@@ -3369,17 +3526,17 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                                        "command failed (x%x)\n", rc);
                break;
 
-       case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
+       case LPFC_FIP_EVENT_TYPE_FCF_TABLE_FULL:
                lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
                        "2548 FCF Table full count 0x%x tag 0x%x\n",
-                       bf_get(lpfc_acqe_fcoe_fcf_count, acqe_fcoe),
-                       acqe_fcoe->event_tag);
+                       bf_get(lpfc_acqe_fip_fcf_count, acqe_fip),
+                       acqe_fip->event_tag);
                break;
 
-       case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
+       case LPFC_FIP_EVENT_TYPE_FCF_DEAD:
                lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
                        "2549 FCF (x%x) disconnected from network, "
-                       "tag:x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
+                       "tag:x%x\n", acqe_fip->index, acqe_fip->event_tag);
                /*
                 * If we are in the middle of FCF failover process, clear
                 * the corresponding FCF bit in the roundrobin bitmap.
@@ -3388,13 +3545,13 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
                        spin_unlock_irq(&phba->hbalock);
                        /* Update FLOGI FCF failover eligible FCF bmask */
-                       lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index);
+                       lpfc_sli4_fcf_rr_index_clear(phba, acqe_fip->index);
                        break;
                }
                spin_unlock_irq(&phba->hbalock);
 
                /* If the event is not for currently used fcf do nothing */
-               if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index)
+               if (phba->fcf.current_rec.fcf_indx != acqe_fip->index)
                        break;
 
                /*
@@ -3411,7 +3568,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
                                "2771 Start FCF fast failover process due to "
                                "FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
-                               "\n", acqe_fcoe->event_tag, acqe_fcoe->index);
+                               "\n", acqe_fip->event_tag, acqe_fip->index);
                rc = lpfc_sli4_redisc_fcf_table(phba);
                if (rc) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
@@ -3438,12 +3595,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                        lpfc_sli4_perform_all_vport_cvl(phba);
                }
                break;
-       case LPFC_FCOE_EVENT_TYPE_CVL:
+       case LPFC_FIP_EVENT_TYPE_CVL:
                lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
                        "2718 Clear Virtual Link Received for VPI 0x%x"
-                       " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
+                       " tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag);
                vport = lpfc_find_vport_by_vpid(phba,
-                               acqe_fcoe->index - phba->vpi_base);
+                               acqe_fip->index - phba->vpi_base);
                ndlp = lpfc_sli4_perform_vport_cvl(vport);
                if (!ndlp)
                        break;
@@ -3494,7 +3651,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                        lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
                                        LOG_DISCOVERY,
                                        "2773 Start FCF failover per CVL, "
-                                       "evt_tag:x%x\n", acqe_fcoe->event_tag);
+                                       "evt_tag:x%x\n", acqe_fip->event_tag);
                        rc = lpfc_sli4_redisc_fcf_table(phba);
                        if (rc) {
                                lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
@@ -3522,7 +3679,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
        default:
                lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
                        "0288 Unknown FCoE event type 0x%x event tag "
-                       "0x%x\n", event_type, acqe_fcoe->event_tag);
+                       "0x%x\n", event_type, acqe_fip->event_tag);
                break;
        }
 }
@@ -3599,8 +3756,7 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba)
                                                 &cq_event->cqe.acqe_link);
                        break;
                case LPFC_TRAILER_CODE_FCOE:
-                       lpfc_sli4_async_fcoe_evt(phba,
-                                                &cq_event->cqe.acqe_fcoe);
+                       lpfc_sli4_async_fip_evt(phba, &cq_event->cqe.acqe_fip);
                        break;
                case LPFC_TRAILER_CODE_DCBX:
                        lpfc_sli4_async_dcbx_evt(phba,
@@ -3610,6 +3766,12 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba)
                        lpfc_sli4_async_grp5_evt(phba,
                                                 &cq_event->cqe.acqe_grp5);
                        break;
+               case LPFC_TRAILER_CODE_FC:
+                       lpfc_sli4_async_fc_evt(phba, &cq_event->cqe.acqe_fc);
+                       break;
+               case LPFC_TRAILER_CODE_SLI:
+                       lpfc_sli4_async_sli_evt(phba, &cq_event->cqe.acqe_sli);
+                       break;
                default:
                        lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
                                        "1804 Invalid asynchrous event code: "
@@ -3948,7 +4110,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
        int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size;
        uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
        struct lpfc_mqe *mqe;
-       int longs;
+       int longs, sli_family;
 
        /* Before proceed, wait for POST done and device ready */
        rc = lpfc_sli4_post_status_check(phba);
@@ -3963,6 +4125,9 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
        init_timer(&phba->hb_tmofunc);
        phba->hb_tmofunc.function = lpfc_hb_timeout;
        phba->hb_tmofunc.data = (unsigned long)phba;
+       init_timer(&phba->rrq_tmr);
+       phba->rrq_tmr.function = lpfc_rrq_timeout;
+       phba->rrq_tmr.data = (unsigned long)phba;
 
        psli = &phba->sli;
        /* MBOX heartbeat timer */
@@ -4010,12 +4175,22 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
         */
        buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) +
                    ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge)));
-       /* Feature Level 1 hardware is limited to 2 pages */
-       if ((bf_get(lpfc_sli_intf_featurelevel1, &phba->sli4_hba.sli_intf) ==
-            LPFC_SLI_INTF_FEATURELEVEL1_1))
-               max_buf_size = LPFC_SLI4_FL1_MAX_BUF_SIZE;
-       else
-               max_buf_size = LPFC_SLI4_MAX_BUF_SIZE;
+
+       sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf);
+       max_buf_size = LPFC_SLI4_MAX_BUF_SIZE;
+       switch (sli_family) {
+       case LPFC_SLI_INTF_FAMILY_BE2:
+       case LPFC_SLI_INTF_FAMILY_BE3:
+               /* There is a single hint for BE - 2 pages per BPL. */
+               if (bf_get(lpfc_sli_intf_sli_hint1, &phba->sli4_hba.sli_intf) ==
+                   LPFC_SLI_INTF_SLI_HINT1_1)
+                       max_buf_size = LPFC_SLI4_FL1_MAX_BUF_SIZE;
+               break;
+       case LPFC_SLI_INTF_FAMILY_LNCR_A0:
+       case LPFC_SLI_INTF_FAMILY_LNCR_B0:
+       default:
+               break;
+       }
        for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE;
             dma_buf_size < max_buf_size && buf_size > dma_buf_size;
             dma_buf_size = dma_buf_size << 1)
@@ -4070,6 +4245,14 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
        if (rc)
                return -ENOMEM;
 
+       /* IF Type 2 ports get initialized now. */
+       if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+           LPFC_SLI_INTF_IF_TYPE_2) {
+               rc = lpfc_pci_function_reset(phba);
+               if (unlikely(rc))
+                       return -ENODEV;
+       }
+
        /* Create the bootstrap mailbox command */
        rc = lpfc_create_bootstrap_mbox(phba);
        if (unlikely(rc))
@@ -4080,19 +4263,18 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
        if (unlikely(rc))
                goto out_free_bsmbx;
 
-       rc = lpfc_sli4_fw_cfg_check(phba);
-       if (unlikely(rc))
-               goto out_free_bsmbx;
-
        /* Set up the hba's configuration parameters. */
        rc = lpfc_sli4_read_config(phba);
        if (unlikely(rc))
                goto out_free_bsmbx;
 
-       /* Perform a function reset */
-       rc = lpfc_pci_function_reset(phba);
-       if (unlikely(rc))
-               goto out_free_bsmbx;
+       /* IF Type 0 ports get initialized now. */
+       if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+           LPFC_SLI_INTF_IF_TYPE_0) {
+               rc = lpfc_pci_function_reset(phba);
+               if (unlikely(rc))
+                       goto out_free_bsmbx;
+       }
 
        mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
                                                       GFP_KERNEL);
@@ -5190,97 +5372,183 @@ lpfc_sli_pci_mem_unset(struct lpfc_hba *phba)
 int
 lpfc_sli4_post_status_check(struct lpfc_hba *phba)
 {
-       struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg;
-       int i, port_error = -ENODEV;
+       struct lpfc_register portsmphr_reg, uerrlo_reg, uerrhi_reg;
+       struct lpfc_register reg_data;
+       int i, port_error = 0;
+       uint32_t if_type;
 
-       if (!phba->sli4_hba.STAregaddr)
+       if (!phba->sli4_hba.PSMPHRregaddr)
                return -ENODEV;
 
        /* Wait up to 30 seconds for the SLI Port POST done and ready */
        for (i = 0; i < 3000; i++) {
-               sta_reg.word0 = readl(phba->sli4_hba.STAregaddr);
-               /* Encounter fatal POST error, break out */
-               if (bf_get(lpfc_hst_state_perr, &sta_reg)) {
+               portsmphr_reg.word0 = readl(phba->sli4_hba.PSMPHRregaddr);
+               if (bf_get(lpfc_port_smphr_perr, &portsmphr_reg)) {
+                       /* Port has a fatal POST error, break out */
                        port_error = -ENODEV;
                        break;
                }
-               if (LPFC_POST_STAGE_ARMFW_READY ==
-                   bf_get(lpfc_hst_state_port_status, &sta_reg)) {
-                       port_error = 0;
+               if (LPFC_POST_STAGE_PORT_READY ==
+                   bf_get(lpfc_port_smphr_port_status, &portsmphr_reg))
                        break;
-               }
                msleep(10);
        }
 
-       if (port_error)
+       /*
+        * If there was a port error during POST, then don't proceed with
+        * other register reads as the data may not be valid.  Just exit.
+        */
+       if (port_error) {
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                       "1408 Failure HBA POST Status: sta_reg=0x%x, "
-                       "perr=x%x, sfi=x%x, nip=x%x, ipc=x%x, xrom=x%x, "
-                       "dl=x%x, pstatus=x%x\n", sta_reg.word0,
-                       bf_get(lpfc_hst_state_perr, &sta_reg),
-                       bf_get(lpfc_hst_state_sfi, &sta_reg),
-                       bf_get(lpfc_hst_state_nip, &sta_reg),
-                       bf_get(lpfc_hst_state_ipc, &sta_reg),
-                       bf_get(lpfc_hst_state_xrom, &sta_reg),
-                       bf_get(lpfc_hst_state_dl, &sta_reg),
-                       bf_get(lpfc_hst_state_port_status, &sta_reg));
-
-       /* Log device information */
-       phba->sli4_hba.sli_intf.word0 = readl(phba->sli4_hba.SLIINTFregaddr);
-       if (bf_get(lpfc_sli_intf_valid,
-                  &phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_VALID) {
+                       "1408 Port Failed POST - portsmphr=0x%x, "
+                       "perr=x%x, sfi=x%x, nip=x%x, ipc=x%x, scr1=x%x, "
+                       "scr2=x%x, hscratch=x%x, pstatus=x%x\n",
+                       portsmphr_reg.word0,
+                       bf_get(lpfc_port_smphr_perr, &portsmphr_reg),
+                       bf_get(lpfc_port_smphr_sfi, &portsmphr_reg),
+                       bf_get(lpfc_port_smphr_nip, &portsmphr_reg),
+                       bf_get(lpfc_port_smphr_ipc, &portsmphr_reg),
+                       bf_get(lpfc_port_smphr_scr1, &portsmphr_reg),
+                       bf_get(lpfc_port_smphr_scr2, &portsmphr_reg),
+                       bf_get(lpfc_port_smphr_host_scratch, &portsmphr_reg),
+                       bf_get(lpfc_port_smphr_port_status, &portsmphr_reg));
+       } else {
                lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                               "2534 Device Info: ChipType=0x%x, SliRev=0x%x, "
-                               "FeatureL1=0x%x, FeatureL2=0x%x\n",
+                               "2534 Device Info: SLIFamily=0x%x, "
+                               "SLIRev=0x%x, IFType=0x%x, SLIHint_1=0x%x, "
+                               "SLIHint_2=0x%x, FT=0x%x\n",
                                bf_get(lpfc_sli_intf_sli_family,
                                       &phba->sli4_hba.sli_intf),
                                bf_get(lpfc_sli_intf_slirev,
                                       &phba->sli4_hba.sli_intf),
-                               bf_get(lpfc_sli_intf_featurelevel1,
+                               bf_get(lpfc_sli_intf_if_type,
+                                      &phba->sli4_hba.sli_intf),
+                               bf_get(lpfc_sli_intf_sli_hint1,
                                       &phba->sli4_hba.sli_intf),
-                               bf_get(lpfc_sli_intf_featurelevel2,
+                               bf_get(lpfc_sli_intf_sli_hint2,
+                                      &phba->sli4_hba.sli_intf),
+                               bf_get(lpfc_sli_intf_func_type,
                                       &phba->sli4_hba.sli_intf));
+               /*
+                * Check for other Port errors during the initialization
+                * process.  Fail the load if the port did not come up
+                * correctly.
+                */
+               if_type = bf_get(lpfc_sli_intf_if_type,
+                                &phba->sli4_hba.sli_intf);
+               switch (if_type) {
+               case LPFC_SLI_INTF_IF_TYPE_0:
+                       phba->sli4_hba.ue_mask_lo =
+                             readl(phba->sli4_hba.u.if_type0.UEMASKLOregaddr);
+                       phba->sli4_hba.ue_mask_hi =
+                             readl(phba->sli4_hba.u.if_type0.UEMASKHIregaddr);
+                       uerrlo_reg.word0 =
+                             readl(phba->sli4_hba.u.if_type0.UERRLOregaddr);
+                       uerrhi_reg.word0 =
+                               readl(phba->sli4_hba.u.if_type0.UERRHIregaddr);
+                       if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) ||
+                           (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) {
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                               "1422 Unrecoverable Error "
+                                               "Detected during POST "
+                                               "uerr_lo_reg=0x%x, "
+                                               "uerr_hi_reg=0x%x, "
+                                               "ue_mask_lo_reg=0x%x, "
+                                               "ue_mask_hi_reg=0x%x\n",
+                                               uerrlo_reg.word0,
+                                               uerrhi_reg.word0,
+                                               phba->sli4_hba.ue_mask_lo,
+                                               phba->sli4_hba.ue_mask_hi);
+                               port_error = -ENODEV;
+                       }
+                       break;
+               case LPFC_SLI_INTF_IF_TYPE_2:
+                       /* Final checks.  The port status should be clean. */
+                       reg_data.word0 =
+                               readl(phba->sli4_hba.u.if_type2.STATUSregaddr);
+                       if (bf_get(lpfc_sliport_status_err, &reg_data)) {
+                               phba->work_status[0] =
+                                       readl(phba->sli4_hba.u.if_type2.
+                                             ERR1regaddr);
+                               phba->work_status[1] =
+                                       readl(phba->sli4_hba.u.if_type2.
+                                             ERR2regaddr);
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "2888 Port Error Detected "
+                                       "during POST: "
+                                       "port status reg 0x%x, "
+                                       "port_smphr reg 0x%x, "
+                                       "error 1=0x%x, error 2=0x%x\n",
+                                       reg_data.word0,
+                                       portsmphr_reg.word0,
+                                       phba->work_status[0],
+                                       phba->work_status[1]);
+                               port_error = -ENODEV;
+                       }
+                       break;
+               case LPFC_SLI_INTF_IF_TYPE_1:
+               default:
+                       break;
+               }
        }
-       phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr);
-       phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr);
-       /* With uncoverable error, log the error message and return error */
-       uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
-       uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
-       if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) ||
-           (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "1422 HBA Unrecoverable error: "
-                               "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
-                               "ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
-                               uerrlo_reg.word0, uerrhi_reg.word0,
-                               phba->sli4_hba.ue_mask_lo,
-                               phba->sli4_hba.ue_mask_hi);
-               return -ENODEV;
-       }
-
        return port_error;
 }
 
 /**
  * lpfc_sli4_bar0_register_memmap - Set up SLI4 BAR0 register memory map.
  * @phba: pointer to lpfc hba data structure.
+ * @if_type:  The SLI4 interface type getting configured.
  *
  * This routine is invoked to set up SLI4 BAR0 PCI config space register
  * memory map.
  **/
 static void
-lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba)
-{
-       phba->sli4_hba.UERRLOregaddr = phba->sli4_hba.conf_regs_memmap_p +
-                                       LPFC_UERR_STATUS_LO;
-       phba->sli4_hba.UERRHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
-                                       LPFC_UERR_STATUS_HI;
-       phba->sli4_hba.UEMASKLOregaddr = phba->sli4_hba.conf_regs_memmap_p +
-                                       LPFC_UE_MASK_LO;
-       phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
-                                       LPFC_UE_MASK_HI;
-       phba->sli4_hba.SLIINTFregaddr = phba->sli4_hba.conf_regs_memmap_p +
-                                       LPFC_SLI_INTF;
+lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type)
+{
+       switch (if_type) {
+       case LPFC_SLI_INTF_IF_TYPE_0:
+               phba->sli4_hba.u.if_type0.UERRLOregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_UERR_STATUS_LO;
+               phba->sli4_hba.u.if_type0.UERRHIregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_UERR_STATUS_HI;
+               phba->sli4_hba.u.if_type0.UEMASKLOregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_UE_MASK_LO;
+               phba->sli4_hba.u.if_type0.UEMASKHIregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_UE_MASK_HI;
+               phba->sli4_hba.SLIINTFregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF;
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_2:
+               phba->sli4_hba.u.if_type2.ERR1regaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_1;
+               phba->sli4_hba.u.if_type2.ERR2regaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_2;
+               phba->sli4_hba.u.if_type2.CTRLregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_CNTRL;
+               phba->sli4_hba.u.if_type2.STATUSregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_STATUS;
+               phba->sli4_hba.SLIINTFregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF;
+               phba->sli4_hba.PSMPHRregaddr =
+                    phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_IF2_SMPHR;
+               phba->sli4_hba.RQDBregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_RQ_DOORBELL;
+               phba->sli4_hba.WQDBregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_WQ_DOORBELL;
+               phba->sli4_hba.EQCQDBregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL;
+               phba->sli4_hba.MQDBregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL;
+               phba->sli4_hba.BMBXregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX;
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_1:
+       default:
+               dev_printk(KERN_ERR, &phba->pcidev->dev,
+                          "FATAL - unsupported SLI4 interface type - %d\n",
+                          if_type);
+               break;
+       }
 }
 
 /**
@@ -5293,16 +5561,14 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba)
 static void
 lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba)
 {
-
-       phba->sli4_hba.STAregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
-                                   LPFC_HST_STATE;
+       phba->sli4_hba.PSMPHRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
+               LPFC_SLIPORT_IF0_SMPHR;
        phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
-                                   LPFC_HST_ISR0;
+               LPFC_HST_ISR0;
        phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
-                                   LPFC_HST_IMR0;
+               LPFC_HST_IMR0;
        phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p +
-                                    LPFC_HST_ISCR0;
-       return;
+               LPFC_HST_ISCR0;
 }
 
 /**
@@ -5542,11 +5808,12 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
 }
 
 /**
- * lpfc_dev_endian_order_setup - Notify the port of the host's endian order.
+ * lpfc_setup_endian_order - Write endian order to an SLI4 if_type 0 port.
  * @phba: pointer to lpfc hba data structure.
  *
- * This routine is invoked to setup the host-side endian order to the
- * HBA consistent with the SLI-4 interface spec.
+ * This routine is invoked to setup the port-side endian order when
+ * the port if_type is 0.  This routine has no function for other
+ * if_types.
  *
  * Return codes
  *     0 - successful
@@ -5557,34 +5824,44 @@ static int
 lpfc_setup_endian_order(struct lpfc_hba *phba)
 {
        LPFC_MBOXQ_t *mboxq;
-       uint32_t rc = 0;
+       uint32_t if_type, rc = 0;
        uint32_t endian_mb_data[2] = {HOST_ENDIAN_LOW_WORD0,
                                      HOST_ENDIAN_HIGH_WORD1};
 
-       mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-       if (!mboxq) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "0492 Unable to allocate memory for issuing "
-                               "SLI_CONFIG_SPECIAL mailbox command\n");
-               return -ENOMEM;
-       }
+       if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+       switch (if_type) {
+       case LPFC_SLI_INTF_IF_TYPE_0:
+               mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
+                                                      GFP_KERNEL);
+               if (!mboxq) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "0492 Unable to allocate memory for "
+                                       "issuing SLI_CONFIG_SPECIAL mailbox "
+                                       "command\n");
+                       return -ENOMEM;
+               }
 
-       /*
-        * The SLI4_CONFIG_SPECIAL mailbox command requires the first two
-        * words to contain special data values and no other data.
-        */
-       memset(mboxq, 0, sizeof(LPFC_MBOXQ_t));
-       memcpy(&mboxq->u.mqe, &endian_mb_data, sizeof(endian_mb_data));
-       rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
-       if (rc != MBX_SUCCESS) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "0493 SLI_CONFIG_SPECIAL mailbox failed with "
-                               "status x%x\n",
-                               rc);
-               rc = -EIO;
+               /*
+                * The SLI4_CONFIG_SPECIAL mailbox command requires the first
+                * two words to contain special data values and no other data.
+                */
+               memset(mboxq, 0, sizeof(LPFC_MBOXQ_t));
+               memcpy(&mboxq->u.mqe, &endian_mb_data, sizeof(endian_mb_data));
+               rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+               if (rc != MBX_SUCCESS) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "0493 SLI_CONFIG_SPECIAL mailbox "
+                                       "failed with status x%x\n",
+                                       rc);
+                       rc = -EIO;
+               }
+               mempool_free(mboxq, phba->mbox_mem_pool);
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_2:
+       case LPFC_SLI_INTF_IF_TYPE_1:
+       default:
+               break;
        }
-
-       mempool_free(mboxq, phba->mbox_mem_pool);
        return rc;
 }
 
@@ -6416,36 +6693,124 @@ int
 lpfc_pci_function_reset(struct lpfc_hba *phba)
 {
        LPFC_MBOXQ_t *mboxq;
-       uint32_t rc = 0;
+       uint32_t rc = 0, if_type;
        uint32_t shdr_status, shdr_add_status;
+       uint32_t rdy_chk, num_resets = 0, reset_again = 0;
        union lpfc_sli4_cfg_shdr *shdr;
+       struct lpfc_register reg_data;
 
-       mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-       if (!mboxq) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "0494 Unable to allocate memory for issuing "
-                               "SLI_FUNCTION_RESET mailbox command\n");
-               return -ENOMEM;
-       }
+       if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+       switch (if_type) {
+       case LPFC_SLI_INTF_IF_TYPE_0:
+               mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
+                                                      GFP_KERNEL);
+               if (!mboxq) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "0494 Unable to allocate memory for "
+                                       "issuing SLI_FUNCTION_RESET mailbox "
+                                       "command\n");
+                       return -ENOMEM;
+               }
 
-       /* Set up PCI function reset SLI4_CONFIG mailbox-ioctl command */
-       lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
-                        LPFC_MBOX_OPCODE_FUNCTION_RESET, 0,
-                        LPFC_SLI4_MBX_EMBED);
-       rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
-       shdr = (union lpfc_sli4_cfg_shdr *)
-               &mboxq->u.mqe.un.sli4_config.header.cfg_shdr;
-       shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
-       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
-       if (rc != MBX_TIMEOUT)
-               mempool_free(mboxq, phba->mbox_mem_pool);
-       if (shdr_status || shdr_add_status || rc) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "0495 SLI_FUNCTION_RESET mailbox failed with "
-                               "status x%x add_status x%x, mbx status x%x\n",
-                               shdr_status, shdr_add_status, rc);
-               rc = -ENXIO;
+               /* Setup PCI function reset mailbox-ioctl command */
+               lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
+                                LPFC_MBOX_OPCODE_FUNCTION_RESET, 0,
+                                LPFC_SLI4_MBX_EMBED);
+               rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+               shdr = (union lpfc_sli4_cfg_shdr *)
+                       &mboxq->u.mqe.un.sli4_config.header.cfg_shdr;
+               shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+               shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+                                        &shdr->response);
+               if (rc != MBX_TIMEOUT)
+                       mempool_free(mboxq, phba->mbox_mem_pool);
+               if (shdr_status || shdr_add_status || rc) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "0495 SLI_FUNCTION_RESET mailbox "
+                                       "failed with status x%x add_status x%x,"
+                                       " mbx status x%x\n",
+                                       shdr_status, shdr_add_status, rc);
+                       rc = -ENXIO;
+               }
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_2:
+               for (num_resets = 0;
+                    num_resets < MAX_IF_TYPE_2_RESETS;
+                    num_resets++) {
+                       reg_data.word0 = 0;
+                       bf_set(lpfc_sliport_ctrl_end, &reg_data,
+                              LPFC_SLIPORT_LITTLE_ENDIAN);
+                       bf_set(lpfc_sliport_ctrl_ip, &reg_data,
+                              LPFC_SLIPORT_INIT_PORT);
+                       writel(reg_data.word0, phba->sli4_hba.u.if_type2.
+                              CTRLregaddr);
+
+                       /*
+                        * Poll the Port Status Register and wait for RDY for
+                        * up to 10 seconds.  If the port doesn't respond, treat
+                        * it as an error.  If the port responds with RN, start
+                        * the loop again.
+                        */
+                       for (rdy_chk = 0; rdy_chk < 1000; rdy_chk++) {
+                               reg_data.word0 =
+                                       readl(phba->sli4_hba.u.if_type2.
+                                             STATUSregaddr);
+                               if (bf_get(lpfc_sliport_status_rdy, &reg_data))
+                                       break;
+                               if (bf_get(lpfc_sliport_status_rn, &reg_data)) {
+                                       reset_again++;
+                                       break;
+                               }
+                               msleep(10);
+                       }
+
+                       /*
+                        * If the port responds to the init request with
+                        * reset needed, delay for a bit and restart the loop.
+                        */
+                       if (reset_again) {
+                               msleep(10);
+                               reset_again = 0;
+                               continue;
+                       }
+
+                       /* Detect any port errors. */
+                       reg_data.word0 = readl(phba->sli4_hba.u.if_type2.
+                                              STATUSregaddr);
+                       if ((bf_get(lpfc_sliport_status_err, &reg_data)) ||
+                           (rdy_chk >= 1000)) {
+                               phba->work_status[0] = readl(
+                                       phba->sli4_hba.u.if_type2.ERR1regaddr);
+                               phba->work_status[1] = readl(
+                                       phba->sli4_hba.u.if_type2.ERR2regaddr);
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "2890 Port Error Detected "
+                                       "during Port Reset: "
+                                       "port status reg 0x%x, "
+                                       "error 1=0x%x, error 2=0x%x\n",
+                                       reg_data.word0,
+                                       phba->work_status[0],
+                                       phba->work_status[1]);
+                               rc = -ENODEV;
+                       }
+
+                       /*
+                        * Terminate the outer loop provided the Port indicated
+                        * ready within 10 seconds.
+                        */
+                       if (rdy_chk < 1000)
+                               break;
+               }
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_1:
+       default:
+               break;
        }
+
+       /* Catch the not-ready port failure after a port reset. */
+       if (num_resets >= MAX_IF_TYPE_2_RESETS)
+               rc = -ENODEV;
+
        return rc;
 }
 
@@ -6536,6 +6901,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
        struct pci_dev *pdev;
        unsigned long bar0map_len, bar1map_len, bar2map_len;
        int error = -ENODEV;
+       uint32_t if_type;
 
        /* Obtain PCI device reference */
        if (!phba->pcidev)
@@ -6552,61 +6918,105 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
                }
        }
 
-       /* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the
-        * number of bytes required by each mapping. They are actually
-        * mapping to the PCI BAR regions 0 or 1, 2, and 4 by the SLI4 device.
+       /*
+        * The BARs and register set definitions and offset locations are
+        * dependent on the if_type.
+        */
+       if (pci_read_config_dword(pdev, LPFC_SLI_INTF,
+                                 &phba->sli4_hba.sli_intf.word0)) {
+               return error;
+       }
+
+       /* There is no SLI3 failback for SLI4 devices. */
+       if (bf_get(lpfc_sli_intf_valid, &phba->sli4_hba.sli_intf) !=
+           LPFC_SLI_INTF_VALID) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "2894 SLI_INTF reg contents invalid "
+                               "sli_intf reg 0x%x\n",
+                               phba->sli4_hba.sli_intf.word0);
+               return error;
+       }
+
+       if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+       /*
+        * Get the bus address of SLI4 device Bar regions and the
+        * number of bytes required by each mapping. The mapping of the
+        * particular PCI BARs regions is dependent on the type of
+        * SLI4 device.
         */
        if (pci_resource_start(pdev, 0)) {
                phba->pci_bar0_map = pci_resource_start(pdev, 0);
                bar0map_len = pci_resource_len(pdev, 0);
+
+               /*
+                * Map SLI4 PCI Config Space Register base to a kernel virtual
+                * addr
+                */
+               phba->sli4_hba.conf_regs_memmap_p =
+                       ioremap(phba->pci_bar0_map, bar0map_len);
+               if (!phba->sli4_hba.conf_regs_memmap_p) {
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "ioremap failed for SLI4 PCI config "
+                                  "registers.\n");
+                       goto out;
+               }
+               /* Set up BAR0 PCI config space register memory map */
+               lpfc_sli4_bar0_register_memmap(phba, if_type);
        } else {
                phba->pci_bar0_map = pci_resource_start(pdev, 1);
                bar0map_len = pci_resource_len(pdev, 1);
-       }
-       phba->pci_bar1_map = pci_resource_start(pdev, 2);
-       bar1map_len = pci_resource_len(pdev, 2);
-
-       phba->pci_bar2_map = pci_resource_start(pdev, 4);
-       bar2map_len = pci_resource_len(pdev, 4);
-
-       /* Map SLI4 PCI Config Space Register base to a kernel virtual addr */
-       phba->sli4_hba.conf_regs_memmap_p =
+               if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
+                       dev_printk(KERN_ERR, &pdev->dev,
+                          "FATAL - No BAR0 mapping for SLI4, if_type 2\n");
+                       goto out;
+               }
+               phba->sli4_hba.conf_regs_memmap_p =
                                ioremap(phba->pci_bar0_map, bar0map_len);
-       if (!phba->sli4_hba.conf_regs_memmap_p) {
-               dev_printk(KERN_ERR, &pdev->dev,
-                          "ioremap failed for SLI4 PCI config registers.\n");
-               goto out;
+               if (!phba->sli4_hba.conf_regs_memmap_p) {
+                       dev_printk(KERN_ERR, &pdev->dev,
+                               "ioremap failed for SLI4 PCI config "
+                               "registers.\n");
+                               goto out;
+               }
+               lpfc_sli4_bar0_register_memmap(phba, if_type);
        }
 
-       /* Map SLI4 HBA Control Register base to a kernel virtual address. */
-       phba->sli4_hba.ctrl_regs_memmap_p =
+       if (pci_resource_start(pdev, 2)) {
+               /*
+                * Map SLI4 if type 0 HBA Control Register base to a kernel
+                * virtual address and setup the registers.
+                */
+               phba->pci_bar1_map = pci_resource_start(pdev, 2);
+               bar1map_len = pci_resource_len(pdev, 2);
+               phba->sli4_hba.ctrl_regs_memmap_p =
                                ioremap(phba->pci_bar1_map, bar1map_len);
-       if (!phba->sli4_hba.ctrl_regs_memmap_p) {
-               dev_printk(KERN_ERR, &pdev->dev,
+               if (!phba->sli4_hba.ctrl_regs_memmap_p) {
+                       dev_printk(KERN_ERR, &pdev->dev,
                           "ioremap failed for SLI4 HBA control registers.\n");
-               goto out_iounmap_conf;
+                       goto out_iounmap_conf;
+               }
+               lpfc_sli4_bar1_register_memmap(phba);
        }
 
-       /* Map SLI4 HBA Doorbell Register base to a kernel virtual address. */
-       phba->sli4_hba.drbl_regs_memmap_p =
+       if (pci_resource_start(pdev, 4)) {
+               /*
+                * Map SLI4 if type 0 HBA Doorbell Register base to a kernel
+                * virtual address and setup the registers.
+                */
+               phba->pci_bar2_map = pci_resource_start(pdev, 4);
+               bar2map_len = pci_resource_len(pdev, 4);
+               phba->sli4_hba.drbl_regs_memmap_p =
                                ioremap(phba->pci_bar2_map, bar2map_len);
-       if (!phba->sli4_hba.drbl_regs_memmap_p) {
-               dev_printk(KERN_ERR, &pdev->dev,
+               if (!phba->sli4_hba.drbl_regs_memmap_p) {
+                       dev_printk(KERN_ERR, &pdev->dev,
                           "ioremap failed for SLI4 HBA doorbell registers.\n");
-               goto out_iounmap_ctrl;
+                       goto out_iounmap_ctrl;
+               }
+               error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0);
+               if (error)
+                       goto out_iounmap_all;
        }
 
-       /* Set up BAR0 PCI config space register memory map */
-       lpfc_sli4_bar0_register_memmap(phba);
-
-       /* Set up BAR1 register memory map */
-       lpfc_sli4_bar1_register_memmap(phba);
-
-       /* Set up BAR2 register memory map */
-       error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0);
-       if (error)
-               goto out_iounmap_all;
-
        return 0;
 
 out_iounmap_all:
@@ -8149,6 +8559,8 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
                goto out_unset_driver_resource_s4;
        }
 
+       INIT_LIST_HEAD(&phba->active_rrq_list);
+
        /* Set up common device driver resources */
        error = lpfc_setup_driver_resource_phase2(phba);
        if (error) {
@@ -8218,7 +8630,11 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
                                "0451 Configure interrupt mode (%d) "
                                "failed active interrupt test.\n",
                                intr_mode);
-               /* Unset the preivous SLI-4 HBA setup */
+               /* Unset the previous SLI-4 HBA setup. */
+               /*
+                * TODO:  Is this operation compatible with IF TYPE 2
+                * devices?  All port state is deleted and cleared.
+                */
                lpfc_sli4_unset_hba(phba);
                /* Try next level of interrupt mode */
                cfg_mode = --intr_mode;
@@ -8990,6 +9406,10 @@ static struct pci_device_id lpfc_id_table[] = {
                PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BALIUS,
                PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FC,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE,
+               PCI_ANY_ID, PCI_ANY_ID, },
        { 0 }
 };
 
index bb59e927312674b4ff6fea061ca6549120290507..e3b790e5915624794284b5c2e420caee58fe6114 100644 (file)
@@ -33,7 +33,7 @@
 #define LOG_FCP_ERROR  0x00001000      /* log errors, not underruns */
 #define LOG_LIBDFC     0x00002000      /* Libdfc events */
 #define LOG_VPORT      0x00004000      /* NPIV events */
-#define LOF_SECURITY   0x00008000      /* Security events */
+#define LOG_SECURITY   0x00008000      /* Security events */
 #define LOG_EVENT      0x00010000      /* CT,TEMP,DUMP, logging */
 #define LOG_FIP                0x00020000      /* FIP events */
 #define LOG_ALL_MSG    0xffffffff      /* LOG all messages */
index 62d0957e1d4c7dd29add28778f640af952e56b47..23403c650207cb187af098519845944fd638c417 100644 (file)
@@ -263,18 +263,19 @@ lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 }
 
 /**
- * lpfc_read_la - Prepare a mailbox command for reading HBA link attention
+ * lpfc_read_topology - Prepare a mailbox command for reading HBA topology
  * @phba: pointer to lpfc hba data structure.
  * @pmb: pointer to the driver internal queue element for mailbox command.
  * @mp: DMA buffer memory for reading the link attention information into.
  *
- * The read link attention mailbox command is issued to read the Link Event
- * Attention information indicated by the HBA port when the Link Event bit
- * of the Host Attention (HSTATT) register is set to 1. A Link Event
+ * The read topology mailbox command is issued to read the link topology
+ * information indicated by the HBA port when the Link Event bit of the Host
+ * Attention (HSTATT) register is set to 1 (For SLI-3) or when an FC Link
+ * Attention ACQE is received from the port (For SLI-4). A Link Event
  * Attention occurs based on an exception detected at the Fibre Channel link
  * interface.
  *
- * This routine prepares the mailbox command for reading HBA link attention
+ * This routine prepares the mailbox command for reading HBA link topology
  * information. A DMA memory has been set aside and address passed to the
  * HBA through @mp for the HBA to DMA link attention information into the
  * memory as part of the execution of the mailbox command.
@@ -283,7 +284,8 @@ lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
  *    0 - Success (currently always return 0)
  **/
 int
-lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
+lpfc_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
+                  struct lpfc_dmabuf *mp)
 {
        MAILBOX_t *mb;
        struct lpfc_sli *psli;
@@ -293,15 +295,15 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
        memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
        INIT_LIST_HEAD(&mp->list);
-       mb->mbxCommand = MBX_READ_LA64;
-       mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
-       mb->un.varReadLA.un.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
-       mb->un.varReadLA.un.lilpBde64.addrLow = putPaddrLow(mp->phys);
+       mb->mbxCommand = MBX_READ_TOPOLOGY;
+       mb->un.varReadTop.lilpBde64.tus.f.bdeSize = LPFC_ALPA_MAP_SIZE;
+       mb->un.varReadTop.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
+       mb->un.varReadTop.lilpBde64.addrLow = putPaddrLow(mp->phys);
 
        /* Save address for later completion and set the owner to host so that
         * the FW knows this mailbox is available for processing.
         */
-       pmb->context1 = (uint8_t *) mp;
+       pmb->context1 = (uint8_t *)mp;
        mb->mbxOwner = OWN_HOST;
        return (0);
 }
@@ -516,18 +518,33 @@ lpfc_init_link(struct lpfc_hba * phba,
        vpd = &phba->vpd;
        if (vpd->rev.feaLevelHigh >= 0x02){
                switch(linkspeed){
-                       case LINK_SPEED_1G:
-                       case LINK_SPEED_2G:
-                       case LINK_SPEED_4G:
-                       case LINK_SPEED_8G:
-                               mb->un.varInitLnk.link_flags |=
-                                                       FLAGS_LINK_SPEED;
-                               mb->un.varInitLnk.link_speed = linkspeed;
+               case LPFC_USER_LINK_SPEED_1G:
+                       mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+                       mb->un.varInitLnk.link_speed = LINK_SPEED_1G;
+                       break;
+               case LPFC_USER_LINK_SPEED_2G:
+                       mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+                       mb->un.varInitLnk.link_speed = LINK_SPEED_2G;
+                       break;
+               case LPFC_USER_LINK_SPEED_4G:
+                       mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+                       mb->un.varInitLnk.link_speed = LINK_SPEED_4G;
+                       break;
+               case LPFC_USER_LINK_SPEED_8G:
+                       mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+                       mb->un.varInitLnk.link_speed = LINK_SPEED_8G;
+                       break;
+               case LPFC_USER_LINK_SPEED_10G:
+                       mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+                       mb->un.varInitLnk.link_speed = LINK_SPEED_10G;
                        break;
-                       case LINK_SPEED_AUTO:
-                       default:
-                               mb->un.varInitLnk.link_speed =
-                                                       LINK_SPEED_AUTO;
+               case LPFC_USER_LINK_SPEED_16G:
+                       mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+                       mb->un.varInitLnk.link_speed = LINK_SPEED_16G;
+                       break;
+               case LPFC_USER_LINK_SPEED_AUTO:
+               default:
+                       mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
                        break;
                }
 
@@ -693,7 +710,7 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
  * @did: remote port identifier.
  * @param: pointer to memory holding the server parameters.
  * @pmb: pointer to the driver internal queue element for mailbox command.
- * @flag: action flag to be passed back for the complete function.
+ * @rpi: the rpi to use in the registration (usually only used for SLI4.
  *
  * The registration login mailbox command is used to register an N_Port or
  * F_Port login. This registration allows the HBA to cache the remote N_Port
@@ -712,7 +729,7 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
  **/
 int
 lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
-              uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
+            uint8_t *param, LPFC_MBOXQ_t *pmb, uint16_t rpi)
 {
        MAILBOX_t *mb = &pmb->u.mb;
        uint8_t *sparam;
@@ -722,17 +739,13 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
 
        mb->un.varRegLogin.rpi = 0;
        if (phba->sli_rev == LPFC_SLI_REV4) {
-               mb->un.varRegLogin.rpi = lpfc_sli4_alloc_rpi(phba);
+               mb->un.varRegLogin.rpi = rpi;
                if (mb->un.varRegLogin.rpi == LPFC_RPI_ALLOC_ERROR)
                        return 1;
        }
-
        mb->un.varRegLogin.vpi = vpi + phba->vpi_base;
        mb->un.varRegLogin.did = did;
-       mb->un.varWords[30] = flag;     /* Set flag to issue action on cmpl */
-
        mb->mbxOwner = OWN_HOST;
-
        /* Get a buffer to hold NPorts Service Parameters */
        mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
        if (mp)
@@ -743,7 +756,7 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
                /* REG_LOGIN: no buffers */
                lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
                                "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
-                               "flag x%x\n", vpi, did, flag);
+                               "rpi x%x\n", vpi, did, rpi);
                return (1);
        }
        INIT_LIST_HEAD(&mp->list);
@@ -1918,11 +1931,14 @@ lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
        struct lpfc_mbx_init_vfi *init_vfi;
 
        memset(mbox, 0, sizeof(*mbox));
+       mbox->vport = vport;
        init_vfi = &mbox->u.mqe.un.init_vfi;
        bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VFI);
        bf_set(lpfc_init_vfi_vr, init_vfi, 1);
        bf_set(lpfc_init_vfi_vt, init_vfi, 1);
+       bf_set(lpfc_init_vfi_vp, init_vfi, 1);
        bf_set(lpfc_init_vfi_vfi, init_vfi, vport->vfi + vport->phba->vfi_base);
+       bf_set(lpfc_init_vpi_vpi, init_vfi, vport->vpi + vport->phba->vpi_base);
        bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi);
 }
 
index 8f879e477e9d3a666f7cc490072cda2b29deaba0..cbb48ee8b0bb05359fbed0afa6cdd2719b8ff00b 100644 (file)
@@ -113,11 +113,16 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align)
                goto fail_free_mbox_pool;
 
        if (phba->sli_rev == LPFC_SLI_REV4) {
+               phba->rrq_pool =
+                       mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
+                                               sizeof(struct lpfc_node_rrq));
+               if (!phba->rrq_pool)
+                       goto fail_free_nlp_mem_pool;
                phba->lpfc_hrb_pool = pci_pool_create("lpfc_hrb_pool",
                                              phba->pcidev,
                                              LPFC_HDR_BUF_SIZE, align, 0);
                if (!phba->lpfc_hrb_pool)
-                       goto fail_free_nlp_mem_pool;
+                       goto fail_free_rrq_mem_pool;
 
                phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool",
                                              phba->pcidev,
@@ -147,6 +152,9 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align)
  fail_free_hrb_pool:
        pci_pool_destroy(phba->lpfc_hrb_pool);
        phba->lpfc_hrb_pool = NULL;
+ fail_free_rrq_mem_pool:
+       mempool_destroy(phba->rrq_pool);
+       phba->rrq_pool = NULL;
  fail_free_nlp_mem_pool:
        mempool_destroy(phba->nlp_mem_pool);
        phba->nlp_mem_pool = NULL;
index bccc9c66fa37b3679e0348272c9511a961fc4436..d85a7423a694652f29449e5463c3840fa7a84c09 100644 (file)
@@ -386,7 +386,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                goto out;
 
        rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
-                           (uint8_t *) sp, mbox, 0);
+                           (uint8_t *) sp, mbox, ndlp->nlp_rpi);
        if (rc) {
                mempool_free(mbox, phba->mbox_mem_pool);
                goto out;
@@ -632,7 +632,7 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 
-       if (!(ndlp->nlp_flag & NLP_RPI_VALID)) {
+       if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
                ndlp->nlp_flag &= ~NLP_NPR_ADISC;
                return 0;
        }
@@ -968,7 +968,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
        lpfc_unreg_rpi(vport, ndlp);
 
        if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID,
-                          (uint8_t *) sp, mbox, 0) == 0) {
+                        (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) {
                switch (ndlp->nlp_DID) {
                case NameServer_DID:
                        mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login;
@@ -1338,12 +1338,6 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
        list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
                if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
                   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
-                       if (phba->sli_rev == LPFC_SLI_REV4) {
-                               spin_unlock_irq(&phba->hbalock);
-                               lpfc_sli4_free_rpi(phba,
-                                       mb->u.mb.un.varRegLogin.rpi);
-                               spin_lock_irq(&phba->hbalock);
-                       }
                        mp = (struct lpfc_dmabuf *) (mb->context1);
                        if (mp) {
                                __lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -1426,7 +1420,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
        }
 
        ndlp->nlp_rpi = mb->un.varWords[0];
-       ndlp->nlp_flag |= NLP_RPI_VALID;
+       ndlp->nlp_flag |= NLP_RPI_REGISTERED;
 
        /* Only if we are not a fabric nport do we issue PRLI */
        if (!(ndlp->nlp_type & NLP_FABRIC)) {
@@ -2027,7 +2021,7 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,
 
        if (!mb->mbxStatus) {
                ndlp->nlp_rpi = mb->un.varWords[0];
-               ndlp->nlp_flag |= NLP_RPI_VALID;
+               ndlp->nlp_flag |= NLP_RPI_REGISTERED;
        } else {
                if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
                        lpfc_drop_node(vport, ndlp);
index f64b65a770b8df3b3f0a3ba47decc0512a8df0a7..c97751c95d77001d80e78ada4adc544fe88d45b7 100644 (file)
@@ -621,10 +621,13 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
                          struct sli4_wcqe_xri_aborted *axri)
 {
        uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
+       uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
        struct lpfc_scsi_buf *psb, *next_psb;
        unsigned long iflag = 0;
        struct lpfc_iocbq *iocbq;
        int i;
+       struct lpfc_nodelist *ndlp;
+       int rrq_empty = 0;
        struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
 
        spin_lock_irqsave(&phba->hbalock, iflag);
@@ -637,8 +640,14 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
                        psb->status = IOSTAT_SUCCESS;
                        spin_unlock(
                                &phba->sli4_hba.abts_scsi_buf_list_lock);
+                       ndlp = psb->rdata->pnode;
+                       rrq_empty = list_empty(&phba->active_rrq_list);
                        spin_unlock_irqrestore(&phba->hbalock, iflag);
+                       if (ndlp)
+                               lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1);
                        lpfc_release_scsi_buf_s4(phba, psb);
+                       if (rrq_empty)
+                               lpfc_worker_wake_up(phba);
                        return;
                }
        }
@@ -914,7 +923,7 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport, int num_to_alloc)
 }
 
 /**
- * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
+ * lpfc_get_scsi_buf_s3 - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
  * @phba: The HBA for which this call is being executed.
  *
  * This routine removes a scsi buffer from head of @phba lpfc_scsi_buf_list list
@@ -925,7 +934,7 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport, int num_to_alloc)
  *   Pointer to lpfc_scsi_buf - Success
  **/
 static struct lpfc_scsi_buf*
-lpfc_get_scsi_buf(struct lpfc_hba * phba)
+lpfc_get_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 {
        struct  lpfc_scsi_buf * lpfc_cmd = NULL;
        struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
@@ -941,6 +950,67 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
        spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
        return  lpfc_cmd;
 }
+/**
+ * lpfc_get_scsi_buf_s4 - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
+ * @phba: The HBA for which this call is being executed.
+ *
+ * This routine removes a scsi buffer from head of @phba lpfc_scsi_buf_list list
+ * and returns to caller.
+ *
+ * Return codes:
+ *   NULL - Error
+ *   Pointer to lpfc_scsi_buf - Success
+ **/
+static struct lpfc_scsi_buf*
+lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+{
+       struct  lpfc_scsi_buf *lpfc_cmd = NULL;
+       struct  lpfc_scsi_buf *start_lpfc_cmd = NULL;
+       struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
+       unsigned long iflag = 0;
+       int found = 0;
+
+       spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
+       list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+       spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
+       while (!found && lpfc_cmd) {
+               if (lpfc_test_rrq_active(phba, ndlp,
+                                        lpfc_cmd->cur_iocbq.sli4_xritag)) {
+                       lpfc_release_scsi_buf_s4(phba, lpfc_cmd);
+                       spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
+                       list_remove_head(scsi_buf_list, lpfc_cmd,
+                                        struct lpfc_scsi_buf, list);
+                       spin_unlock_irqrestore(&phba->scsi_buf_list_lock,
+                                                iflag);
+                       if (lpfc_cmd == start_lpfc_cmd) {
+                               lpfc_cmd = NULL;
+                               break;
+                       } else
+                               continue;
+               }
+               found = 1;
+               lpfc_cmd->seg_cnt = 0;
+               lpfc_cmd->nonsg_phys = 0;
+               lpfc_cmd->prot_seg_cnt = 0;
+       }
+       return  lpfc_cmd;
+}
+/**
+ * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
+ * @phba: The HBA for which this call is being executed.
+ *
+ * This routine removes a scsi buffer from head of @phba lpfc_scsi_buf_list list
+ * and returns to caller.
+ *
+ * Return codes:
+ *   NULL - Error
+ *   Pointer to lpfc_scsi_buf - Success
+ **/
+static struct lpfc_scsi_buf*
+lpfc_get_scsi_buf(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+{
+       return  phba->lpfc_get_scsi_buf(phba, ndlp);
+}
 
 /**
  * lpfc_release_scsi_buf - Return a scsi buffer back to hba scsi buf list
@@ -2744,18 +2814,19 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
 
        phba->lpfc_scsi_unprep_dma_buf = lpfc_scsi_unprep_dma_buf;
        phba->lpfc_scsi_prep_cmnd = lpfc_scsi_prep_cmnd;
-       phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf;
 
        switch (dev_grp) {
        case LPFC_PCI_DEV_LP:
                phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3;
                phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3;
                phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3;
+               phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s3;
                break;
        case LPFC_PCI_DEV_OC:
                phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s4;
                phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4;
                phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4;
+               phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s4;
                break;
        default:
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -2764,7 +2835,6 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
                return -ENODEV;
                break;
        }
-       phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf;
        phba->lpfc_rampdown_queue_depth = lpfc_rampdown_queue_depth;
        phba->lpfc_scsi_cmd_iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl;
        return 0;
@@ -2899,7 +2969,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;
@@ -2940,7 +3010,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
        if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
                goto out_host_busy;
 
-       lpfc_cmd = lpfc_get_scsi_buf(phba);
+       lpfc_cmd = lpfc_get_scsi_buf(phba, ndlp);
        if (lpfc_cmd == NULL) {
                lpfc_rampdown_queue_depth(phba);
 
@@ -3060,6 +3130,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.
@@ -3237,7 +3309,7 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
        if (!pnode || !NLP_CHK_NODE_ACT(pnode))
                return FAILED;
 
-       lpfc_cmd = lpfc_get_scsi_buf(phba);
+       lpfc_cmd = lpfc_get_scsi_buf(phba, rdata->pnode);
        if (lpfc_cmd == NULL)
                return FAILED;
        lpfc_cmd->timeout = 60;
index 554efa6623f4edab7154e3f1ad23e5be845260c6..e98e792ab045e99aca94c8bdef8444df1623a84a 100644 (file)
@@ -512,9 +512,345 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
        return sglq;
 }
 
+/**
+ * __lpfc_set_rrq_active - set RRQ active bit in the ndlp's xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @ndlp: nodelist pointer for this target.
+ * @xritag: xri used in this exchange.
+ * @rxid: Remote Exchange ID.
+ * @send_rrq: Flag used to determine if we should send rrq els cmd.
+ *
+ * This function is called with hbalock held.
+ * The active bit is set in the ndlp's active rrq xri_bitmap. Allocates an
+ * rrq struct and adds it to the active_rrq_list.
+ *
+ * returns  0 for rrq slot for this xri
+ *         < 0  Were not able to get rrq mem or invalid parameter.
+ **/
+static int
+__lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+               uint16_t xritag, uint16_t rxid, uint16_t send_rrq)
+{
+       uint16_t adj_xri;
+       struct lpfc_node_rrq *rrq;
+       int empty;
+
+       /*
+        * set the active bit even if there is no mem available.
+        */
+       adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
+       if (!ndlp)
+               return -EINVAL;
+       if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap))
+               return -EINVAL;
+       rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL);
+       if (rrq) {
+               rrq->send_rrq = send_rrq;
+               rrq->xritag = xritag;
+               rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1);
+               rrq->ndlp = ndlp;
+               rrq->nlp_DID = ndlp->nlp_DID;
+               rrq->vport = ndlp->vport;
+               rrq->rxid = rxid;
+               empty = list_empty(&phba->active_rrq_list);
+               if (phba->cfg_enable_rrq && send_rrq)
+                       /*
+                        * We need the xri before we can add this to the
+                        * phba active rrq list.
+                        */
+                       rrq->send_rrq = send_rrq;
+               else
+                       rrq->send_rrq = 0;
+               list_add_tail(&rrq->list, &phba->active_rrq_list);
+               if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) {
+                       phba->hba_flag |= HBA_RRQ_ACTIVE;
+                       if (empty)
+                               lpfc_worker_wake_up(phba);
+               }
+               return 0;
+       }
+       return -ENOMEM;
+}
+
+/**
+ * __lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @xritag: xri used in this exchange.
+ * @rrq: The RRQ to be cleared.
+ *
+ * This function is called with hbalock held. This function
+ **/
+static void
+__lpfc_clr_rrq_active(struct lpfc_hba *phba,
+                       uint16_t xritag,
+                       struct lpfc_node_rrq *rrq)
+{
+       uint16_t adj_xri;
+       struct lpfc_nodelist *ndlp;
+
+       ndlp = lpfc_findnode_did(rrq->vport, rrq->nlp_DID);
+
+       /* The target DID could have been swapped (cable swap)
+        * we should use the ndlp from the findnode if it is
+        * available.
+        */
+       if (!ndlp)
+               ndlp = rrq->ndlp;
+
+       adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
+       if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) {
+               rrq->send_rrq = 0;
+               rrq->xritag = 0;
+               rrq->rrq_stop_time = 0;
+       }
+       mempool_free(rrq, phba->rrq_pool);
+}
+
+/**
+ * lpfc_handle_rrq_active - Checks if RRQ has waithed RATOV.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called with hbalock held. This function
+ * Checks if stop_time (ratov from setting rrq active) has
+ * been reached, if it has and the send_rrq flag is set then
+ * it will call lpfc_send_rrq. If the send_rrq flag is not set
+ * then it will just call the routine to clear the rrq and
+ * free the rrq resource.
+ * The timer is set to the next rrq that is going to expire before
+ * leaving the routine.
+ *
+ **/
+void
+lpfc_handle_rrq_active(struct lpfc_hba *phba)
+{
+       struct lpfc_node_rrq *rrq;
+       struct lpfc_node_rrq *nextrrq;
+       unsigned long next_time;
+       unsigned long iflags;
+
+       spin_lock_irqsave(&phba->hbalock, iflags);
+       phba->hba_flag &= ~HBA_RRQ_ACTIVE;
+       next_time = jiffies + HZ * (phba->fc_ratov + 1);
+       list_for_each_entry_safe(rrq, nextrrq,
+                       &phba->active_rrq_list, list) {
+               if (time_after(jiffies, rrq->rrq_stop_time)) {
+                       list_del(&rrq->list);
+                       if (!rrq->send_rrq)
+                               /* this call will free the rrq */
+                               __lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
+                       else {
+                       /* if we send the rrq then the completion handler
+                        *  will clear the bit in the xribitmap.
+                        */
+                               spin_unlock_irqrestore(&phba->hbalock, iflags);
+                               if (lpfc_send_rrq(phba, rrq)) {
+                                       lpfc_clr_rrq_active(phba, rrq->xritag,
+                                                                rrq);
+                               }
+                               spin_lock_irqsave(&phba->hbalock, iflags);
+                       }
+               } else if  (time_before(rrq->rrq_stop_time, next_time))
+                       next_time = rrq->rrq_stop_time;
+       }
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
+       if (!list_empty(&phba->active_rrq_list))
+               mod_timer(&phba->rrq_tmr, next_time);
+}
+
+/**
+ * lpfc_get_active_rrq - Get the active RRQ for this exchange.
+ * @vport: Pointer to vport context object.
+ * @xri: The xri used in the exchange.
+ * @did: The targets DID for this exchange.
+ *
+ * returns NULL = rrq not found in the phba->active_rrq_list.
+ *         rrq = rrq for this xri and target.
+ **/
+struct lpfc_node_rrq *
+lpfc_get_active_rrq(struct lpfc_vport *vport, uint16_t xri, uint32_t did)
+{
+       struct lpfc_hba *phba = vport->phba;
+       struct lpfc_node_rrq *rrq;
+       struct lpfc_node_rrq *nextrrq;
+       unsigned long iflags;
+
+       if (phba->sli_rev != LPFC_SLI_REV4)
+               return NULL;
+       spin_lock_irqsave(&phba->hbalock, iflags);
+       list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) {
+               if (rrq->vport == vport && rrq->xritag == xri &&
+                               rrq->nlp_DID == did){
+                       list_del(&rrq->list);
+                       spin_unlock_irqrestore(&phba->hbalock, iflags);
+                       return rrq;
+               }
+       }
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
+       return NULL;
+}
+
+/**
+ * lpfc_cleanup_vports_rrqs - Remove and clear the active RRQ for this vport.
+ * @vport: Pointer to vport context object.
+ *
+ * Remove all active RRQs for this vport from the phba->active_rrq_list and
+ * clear the rrq.
+ **/
+void
+lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport)
+
+{
+       struct lpfc_hba *phba = vport->phba;
+       struct lpfc_node_rrq *rrq;
+       struct lpfc_node_rrq *nextrrq;
+       unsigned long iflags;
+
+       if (phba->sli_rev != LPFC_SLI_REV4)
+               return;
+       spin_lock_irqsave(&phba->hbalock, iflags);
+       list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) {
+               if (rrq->vport == vport) {
+                       list_del(&rrq->list);
+                       __lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
+               }
+       }
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
+}
+
+/**
+ * lpfc_cleanup_wt_rrqs - Remove all rrq's from the active list.
+ * @phba: Pointer to HBA context object.
+ *
+ * Remove all rrqs from the phba->active_rrq_list and free them by
+ * calling __lpfc_clr_active_rrq
+ *
+ **/
+void
+lpfc_cleanup_wt_rrqs(struct lpfc_hba *phba)
+{
+       struct lpfc_node_rrq *rrq;
+       struct lpfc_node_rrq *nextrrq;
+       unsigned long next_time;
+       unsigned long iflags;
+
+       if (phba->sli_rev != LPFC_SLI_REV4)
+               return;
+       spin_lock_irqsave(&phba->hbalock, iflags);
+       phba->hba_flag &= ~HBA_RRQ_ACTIVE;
+       next_time = jiffies + HZ * (phba->fc_ratov * 2);
+       list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) {
+               list_del(&rrq->list);
+               __lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
+       }
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
+       if (!list_empty(&phba->active_rrq_list))
+               mod_timer(&phba->rrq_tmr, next_time);
+}
+
+
+/**
+ * __lpfc_test_rrq_active - Test RRQ bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @ndlp: Targets nodelist pointer for this exchange.
+ * @xritag the xri in the bitmap to test.
+ *
+ * This function is called with hbalock held. This function
+ * returns 0 = rrq not active for this xri
+ *         1 = rrq is valid for this xri.
+ **/
+static int
+__lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+                       uint16_t  xritag)
+{
+       uint16_t adj_xri;
+
+       adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
+       if (!ndlp)
+               return 0;
+       if (test_bit(adj_xri, ndlp->active_rrqs.xri_bitmap))
+                       return 1;
+       else
+               return 0;
+}
+
+/**
+ * lpfc_set_rrq_active - set RRQ active bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @ndlp: nodelist pointer for this target.
+ * @xritag: xri used in this exchange.
+ * @rxid: Remote Exchange ID.
+ * @send_rrq: Flag used to determine if we should send rrq els cmd.
+ *
+ * This function takes the hbalock.
+ * The active bit is always set in the active rrq xri_bitmap even
+ * if there is no slot avaiable for the other rrq information.
+ *
+ * returns 0 rrq actived for this xri
+ *         < 0 No memory or invalid ndlp.
+ **/
+int
+lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+                       uint16_t xritag, uint16_t rxid, uint16_t send_rrq)
+{
+       int ret;
+       unsigned long iflags;
+
+       spin_lock_irqsave(&phba->hbalock, iflags);
+       ret = __lpfc_set_rrq_active(phba, ndlp, xritag, rxid, send_rrq);
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
+       return ret;
+}
+
+/**
+ * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @xritag: xri used in this exchange.
+ * @rrq: The RRQ to be cleared.
+ *
+ * This function is takes the hbalock.
+ **/
+void
+lpfc_clr_rrq_active(struct lpfc_hba *phba,
+                       uint16_t xritag,
+                       struct lpfc_node_rrq *rrq)
+{
+       unsigned long iflags;
+
+       spin_lock_irqsave(&phba->hbalock, iflags);
+       __lpfc_clr_rrq_active(phba, xritag, rrq);
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
+       return;
+}
+
+
+
+/**
+ * lpfc_test_rrq_active - Test RRQ bit in xri_bitmap.
+ * @phba: Pointer to HBA context object.
+ * @ndlp: Targets nodelist pointer for this exchange.
+ * @xritag the xri in the bitmap to test.
+ *
+ * This function takes the hbalock.
+ * returns 0 = rrq not active for this xri
+ *         1 = rrq is valid for this xri.
+ **/
+int
+lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+                       uint16_t  xritag)
+{
+       int ret;
+       unsigned long iflags;
+
+       spin_lock_irqsave(&phba->hbalock, iflags);
+       ret = __lpfc_test_rrq_active(phba, ndlp, xritag);
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
+       return ret;
+}
+
 /**
  * __lpfc_sli_get_sglq - Allocates an iocb object from sgl pool
  * @phba: Pointer to HBA context object.
+ * @piocb: Pointer to the iocbq.
  *
  * This function is called with hbalock held. This function
  * Gets a new driver sglq object from the sglq list. If the
@@ -522,17 +858,51 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
  * allocated sglq object else it returns NULL.
  **/
 static struct lpfc_sglq *
-__lpfc_sli_get_sglq(struct lpfc_hba *phba)
+__lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
 {
        struct list_head *lpfc_sgl_list = &phba->sli4_hba.lpfc_sgl_list;
        struct lpfc_sglq *sglq = NULL;
+       struct lpfc_sglq *start_sglq = NULL;
        uint16_t adj_xri;
+       struct lpfc_scsi_buf *lpfc_cmd;
+       struct lpfc_nodelist *ndlp;
+       int found = 0;
+
+       if (piocbq->iocb_flag &  LPFC_IO_FCP) {
+               lpfc_cmd = (struct lpfc_scsi_buf *) piocbq->context1;
+               ndlp = lpfc_cmd->rdata->pnode;
+       } else  if ((piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) &&
+                       !(piocbq->iocb_flag & LPFC_IO_LIBDFC))
+               ndlp = piocbq->context_un.ndlp;
+       else
+               ndlp = piocbq->context1;
+
        list_remove_head(lpfc_sgl_list, sglq, struct lpfc_sglq, list);
-       if (!sglq)
-               return NULL;
-       adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base;
-       phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
-       sglq->state = SGL_ALLOCATED;
+       start_sglq = sglq;
+       while (!found) {
+               if (!sglq)
+                       return NULL;
+               adj_xri = sglq->sli4_xritag -
+                               phba->sli4_hba.max_cfg_param.xri_base;
+               if (__lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) {
+                       /* This xri has an rrq outstanding for this DID.
+                        * put it back in the list and get another xri.
+                        */
+                       list_add_tail(&sglq->list, lpfc_sgl_list);
+                       sglq = NULL;
+                       list_remove_head(lpfc_sgl_list, sglq,
+                                               struct lpfc_sglq, list);
+                       if (sglq == start_sglq) {
+                               sglq = NULL;
+                               break;
+                       } else
+                               continue;
+               }
+               sglq->ndlp = ndlp;
+               found = 1;
+               phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
+               sglq->state = SGL_ALLOCATED;
+       }
        return sglq;
 }
 
@@ -598,6 +968,7 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
                                &phba->sli4_hba.abts_sgl_list_lock, iflag);
                } else {
                        sglq->state = SGL_FREED;
+                       sglq->ndlp = NULL;
                        list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list);
 
                        /* Check if TXQ queue needs to be serviced */
@@ -1634,7 +2005,6 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
        case MBX_READ_LNK_STAT:
        case MBX_REG_LOGIN:
        case MBX_UNREG_LOGIN:
-       case MBX_READ_LA:
        case MBX_CLEAR_LA:
        case MBX_DUMP_MEMORY:
        case MBX_DUMP_CONTEXT:
@@ -1656,7 +2026,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
        case MBX_READ_SPARM64:
        case MBX_READ_RPI64:
        case MBX_REG_LOGIN64:
-       case MBX_READ_LA64:
+       case MBX_READ_TOPOLOGY:
        case MBX_WRITE_WWN:
        case MBX_SET_DEBUG:
        case MBX_LOAD_EXP_ROM:
@@ -1746,11 +2116,6 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                kfree(mp);
        }
 
-       if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) &&
-           (phba->sli_rev == LPFC_SLI_REV4) &&
-           (pmb->u.mb.un.varUnregLogin.rsvd1 == 0x0))
-               lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi);
-
        /*
         * If a REG_LOGIN succeeded  after node is destroyed or node
         * is in re-discovery driver need to cleanup the RPI.
@@ -3483,12 +3848,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
        phba->pport->fc_myDID = 0;
        phba->pport->fc_prevDID = 0;
 
-       /* Turn off parity checking and serr during the physical reset */
-       pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
-       pci_write_config_word(phba->pcidev, PCI_COMMAND,
-                             (cfg_value &
-                             ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
-
        spin_lock_irq(&phba->hbalock);
        psli->sli_flag &= ~(LPFC_PROCESS_LA);
        phba->fcf.fcf_flag = 0;
@@ -3508,9 +3867,18 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
        /* Now physically reset the device */
        lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
                        "0389 Performing PCI function reset!\n");
+
+       /* Turn off parity checking and serr during the physical reset */
+       pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
+       pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value &
+                             ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
+
        /* Perform FCoE PCI function reset */
        lpfc_pci_function_reset(phba);
 
+       /* Restore PCI cmd register */
+       pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value);
+
        return 0;
 }
 
@@ -4317,6 +4685,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
        struct lpfc_vport *vport = phba->pport;
        struct lpfc_dmabuf *mp;
 
+       /*
+        * TODO:  Why does this routine execute these task in a different
+        * order from probe?
+        */
        /* Perform a PCI function reset to start from clean */
        rc = lpfc_pci_function_reset(phba);
        if (unlikely(rc))
@@ -4357,13 +4729,16 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
        }
 
        rc = lpfc_sli4_read_rev(phba, mboxq, vpd, &vpd_size);
-       if (unlikely(rc))
-               goto out_free_vpd;
-
+       if (unlikely(rc)) {
+               kfree(vpd);
+               goto out_free_mbox;
+       }
        mqe = &mboxq->u.mqe;
        phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev);
        if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev))
-               phba->hba_flag |= HBA_FCOE_SUPPORT;
+               phba->hba_flag |= HBA_FCOE_MODE;
+       else
+               phba->hba_flag &= ~HBA_FCOE_MODE;
 
        if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) ==
                LPFC_DCBX_CEE_MODE)
@@ -4372,13 +4747,14 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                phba->hba_flag &= ~HBA_FIP_SUPPORT;
 
        if (phba->sli_rev != LPFC_SLI_REV4 ||
-           !(phba->hba_flag & HBA_FCOE_SUPPORT)) {
+           !(phba->hba_flag & HBA_FCOE_MODE)) {
                lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
                        "0376 READ_REV Error. SLI Level %d "
                        "FCoE enabled %d\n",
-                       phba->sli_rev, phba->hba_flag & HBA_FCOE_SUPPORT);
+                       phba->sli_rev, phba->hba_flag & HBA_FCOE_MODE);
                rc = -EIO;
-               goto out_free_vpd;
+               kfree(vpd);
+               goto out_free_mbox;
        }
        /*
         * Evaluate the read rev and vpd data. Populate the driver
@@ -4392,6 +4768,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                                "Using defaults.\n", rc);
                rc = 0;
        }
+       kfree(vpd);
 
        /* Save information as VPD data */
        phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev;
@@ -4428,7 +4805,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
        rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
        if (unlikely(rc)) {
                rc = -EIO;
-               goto out_free_vpd;
+               goto out_free_mbox;
        }
 
        /*
@@ -4476,7 +4853,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
        if (rc) {
                phba->link_state = LPFC_HBA_ERROR;
                rc = -ENOMEM;
-               goto out_free_vpd;
+               goto out_free_mbox;
        }
 
        mboxq->vport = vport;
@@ -4501,7 +4878,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                                rc, bf_get(lpfc_mqe_status, mqe));
                phba->link_state = LPFC_HBA_ERROR;
                rc = -EIO;
-               goto out_free_vpd;
+               goto out_free_mbox;
        }
 
        if (phba->cfg_soft_wwnn)
@@ -4526,7 +4903,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                                "0582 Error %d during sgl post operation\n",
                                        rc);
                rc = -ENODEV;
-               goto out_free_vpd;
+               goto out_free_mbox;
        }
 
        /* Register SCSI SGL pool to the device */
@@ -4538,7 +4915,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                /* Some Scsi buffers were moved to the abort scsi list */
                /* A pci function reset will repost them */
                rc = -ENODEV;
-               goto out_free_vpd;
+               goto out_free_mbox;
        }
 
        /* Post the rpi header region to the device. */
@@ -4548,7 +4925,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                                "0393 Error %d during rpi post operation\n",
                                rc);
                rc = -ENODEV;
-               goto out_free_vpd;
+               goto out_free_mbox;
        }
 
        /* Set up all the queues to the device */
@@ -4608,33 +4985,33 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                }
        }
 
+       if (!(phba->hba_flag & HBA_FCOE_MODE)) {
+               /*
+                * The FC Port needs to register FCFI (index 0)
+                */
+               lpfc_reg_fcfi(phba, mboxq);
+               mboxq->vport = phba->pport;
+               rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+               if (rc == MBX_SUCCESS)
+                       rc = 0;
+               else
+                       goto out_unset_queue;
+       }
        /*
         * The port is ready, set the host's link state to LINK_DOWN
         * in preparation for link interrupts.
         */
-       lpfc_init_link(phba, mboxq, phba->cfg_topology, phba->cfg_link_speed);
-       mboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-       lpfc_set_loopback_flag(phba);
-       /* Change driver state to LPFC_LINK_DOWN right before init link */
        spin_lock_irq(&phba->hbalock);
        phba->link_state = LPFC_LINK_DOWN;
        spin_unlock_irq(&phba->hbalock);
-       rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
-       if (unlikely(rc != MBX_NOT_FINISHED)) {
-               kfree(vpd);
-               return 0;
-       } else
-               rc = -EIO;
-
+       rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
+out_unset_queue:
        /* Unset all the queues set up in this routine when error out */
        if (rc)
                lpfc_sli4_queue_unset(phba);
-
 out_stop_timers:
        if (rc)
                lpfc_stop_hba_timers(phba);
-out_free_vpd:
-       kfree(vpd);
 out_free_mbox:
        mempool_free(mboxq, phba->mbox_mem_pool);
        return rc;
@@ -5863,6 +6240,8 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
        IOCB_t *icmd;
        int numBdes = 0;
        int i = 0;
+       uint32_t offset = 0; /* accumulated offset in the sg request list */
+       int inbound = 0; /* number of sg reply entries inbound from firmware */
 
        if (!piocbq || !sglq)
                return xritag;
@@ -5897,6 +6276,20 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
                         */
                        bde.tus.w = le32_to_cpu(bpl->tus.w);
                        sgl->sge_len = cpu_to_le32(bde.tus.f.bdeSize);
+                       /* The offsets in the sgl need to be accumulated
+                        * separately for the request and reply lists.
+                        * The request is always first, the reply follows.
+                        */
+                       if (piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) {
+                               /* add up the reply sg entries */
+                               if (bpl->tus.f.bdeFlags == BUFF_TYPE_BDE_64I)
+                                       inbound++;
+                               /* first inbound? reset the offset */
+                               if (inbound == 1)
+                                       offset = 0;
+                               bf_set(lpfc_sli4_sge_offset, sgl, offset);
+                               offset += bde.tus.f.bdeSize;
+                       }
                        bpl++;
                        sgl++;
                }
@@ -6028,11 +6421,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
                bf_set(els_req64_vf, &wqe->els_req, 0);
                /* And a VFID for word 12 */
                bf_set(els_req64_vfid, &wqe->els_req, 0);
-               /*
-                * Set ct field to 3, indicates that the context_tag field
-                * contains the FCFI and remote N_Port_ID is
-                * in word 5.
-                */
                ct = ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l);
                bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
                       iocbq->iocb.ulpContext);
@@ -6140,6 +6528,18 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
                bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0);
        break;
        case CMD_GEN_REQUEST64_CR:
+               /* For this command calculate the xmit length of the
+                * request bde.
+                */
+               xmit_len = 0;
+               numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize /
+                       sizeof(struct ulp_bde64);
+               for (i = 0; i < numBdes; i++) {
+                       if (bpl[i].tus.f.bdeFlags != BUFF_TYPE_BDE_64)
+                               break;
+                       bde.tus.w = le32_to_cpu(bpl[i].tus.w);
+                       xmit_len += bde.tus.f.bdeSize;
+               }
                /* word3 iocb=IO_TAG wqe=request_payload_len */
                wqe->gen_req.request_payload_len = xmit_len;
                /* word4 iocb=parameter wqe=relative_offset memcpy */
@@ -6320,7 +6720,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
                                        return IOCB_BUSY;
                                }
                        } else {
-                       sglq = __lpfc_sli_get_sglq(phba);
+                       sglq = __lpfc_sli_get_sglq(phba, piocb);
                                if (!sglq) {
                                        if (!(flag & SLI_IOCB_RET_IOCB)) {
                                                __lpfc_sli_ringtx_put(phba,
@@ -8033,29 +8433,66 @@ static int
 lpfc_sli4_eratt_read(struct lpfc_hba *phba)
 {
        uint32_t uerr_sta_hi, uerr_sta_lo;
+       uint32_t if_type, portsmphr;
+       struct lpfc_register portstat_reg;
 
-       /* For now, use the SLI4 device internal unrecoverable error
+       /*
+        * For now, use the SLI4 device internal unrecoverable error
         * registers for error attention. This can be changed later.
         */
-       uerr_sta_lo = readl(phba->sli4_hba.UERRLOregaddr);
-       uerr_sta_hi = readl(phba->sli4_hba.UERRHIregaddr);
-       if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) ||
-           (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) {
+       if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
+       switch (if_type) {
+       case LPFC_SLI_INTF_IF_TYPE_0:
+               uerr_sta_lo = readl(phba->sli4_hba.u.if_type0.UERRLOregaddr);
+               uerr_sta_hi = readl(phba->sli4_hba.u.if_type0.UERRHIregaddr);
+               if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) ||
+                   (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "1423 HBA Unrecoverable error: "
+                                       "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
+                                       "ue_mask_lo_reg=0x%x, "
+                                       "ue_mask_hi_reg=0x%x\n",
+                                       uerr_sta_lo, uerr_sta_hi,
+                                       phba->sli4_hba.ue_mask_lo,
+                                       phba->sli4_hba.ue_mask_hi);
+                       phba->work_status[0] = uerr_sta_lo;
+                       phba->work_status[1] = uerr_sta_hi;
+                       phba->work_ha |= HA_ERATT;
+                       phba->hba_flag |= HBA_ERATT_HANDLED;
+                       return 1;
+               }
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_2:
+               portstat_reg.word0 =
+                       readl(phba->sli4_hba.u.if_type2.STATUSregaddr);
+               portsmphr = readl(phba->sli4_hba.PSMPHRregaddr);
+               if (bf_get(lpfc_sliport_status_err, &portstat_reg)) {
+                       phba->work_status[0] =
+                               readl(phba->sli4_hba.u.if_type2.ERR1regaddr);
+                       phba->work_status[1] =
+                               readl(phba->sli4_hba.u.if_type2.ERR2regaddr);
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "2885 Port Error Detected: "
+                                       "port status reg 0x%x, "
+                                       "port smphr reg 0x%x, "
+                                       "error 1=0x%x, error 2=0x%x\n",
+                                       portstat_reg.word0,
+                                       portsmphr,
+                                       phba->work_status[0],
+                                       phba->work_status[1]);
+                       phba->work_ha |= HA_ERATT;
+                       phba->hba_flag |= HBA_ERATT_HANDLED;
+                       return 1;
+               }
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_1:
+       default:
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "1423 HBA Unrecoverable error: "
-                               "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
-                               "ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
-                               uerr_sta_lo, uerr_sta_hi,
-                               phba->sli4_hba.ue_mask_lo,
-                               phba->sli4_hba.ue_mask_hi);
-               phba->work_status[0] = uerr_sta_lo;
-               phba->work_status[1] = uerr_sta_hi;
-               /* Set the driver HA work bitmap */
-               phba->work_ha |= HA_ERATT;
-               /* Indicate polling handles this ERATT */
-               phba->hba_flag |= HBA_ERATT_HANDLED;
+                               "2886 HBA Error Attention on unsupported "
+                               "if type %d.", if_type);
                return 1;
        }
+
        return 0;
 }
 
@@ -8110,7 +8547,7 @@ lpfc_sli_check_eratt(struct lpfc_hba *phba)
                ha_copy = lpfc_sli_eratt_read(phba);
                break;
        case LPFC_SLI_REV4:
-               /* Read devcie Uncoverable Error (UERR) registers */
+               /* Read device Uncoverable Error (UERR) registers */
                ha_copy = lpfc_sli4_eratt_read(phba);
                break;
        default:
@@ -10155,16 +10592,20 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
                         length, LPFC_SLI4_MBX_EMBED);
 
        mq_create_ext = &mbox->u.mqe.un.mq_create_ext;
-       bf_set(lpfc_mbx_mq_create_ext_num_pages, &mq_create_ext->u.request,
-                   mq->page_count);
-       bf_set(lpfc_mbx_mq_create_ext_async_evt_link, &mq_create_ext->u.request,
-              1);
-       bf_set(lpfc_mbx_mq_create_ext_async_evt_fcfste,
+       bf_set(lpfc_mbx_mq_create_ext_num_pages,
+              &mq_create_ext->u.request, mq->page_count);
+       bf_set(lpfc_mbx_mq_create_ext_async_evt_link,
+              &mq_create_ext->u.request, 1);
+       bf_set(lpfc_mbx_mq_create_ext_async_evt_fip,
               &mq_create_ext->u.request, 1);
        bf_set(lpfc_mbx_mq_create_ext_async_evt_group5,
               &mq_create_ext->u.request, 1);
-       bf_set(lpfc_mq_context_cq_id, &mq_create_ext->u.request.context,
-              cq->queue_id);
+       bf_set(lpfc_mbx_mq_create_ext_async_evt_fc,
+              &mq_create_ext->u.request, 1);
+       bf_set(lpfc_mbx_mq_create_ext_async_evt_sli,
+              &mq_create_ext->u.request, 1);
+       bf_set(lpfc_mq_context_cq_id,
+              &mq_create_ext->u.request.context, cq->queue_id);
        bf_set(lpfc_mq_context_valid, &mq_create_ext->u.request.context, 1);
        switch (mq->entry_count) {
        default:
@@ -11538,6 +11979,10 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
                                "SID:x%x\n", oxid, sid);
                return;
        }
+       if (rxid >= phba->sli4_hba.max_cfg_param.xri_base
+               && rxid <= (phba->sli4_hba.max_cfg_param.max_xri
+               + phba->sli4_hba.max_cfg_param.xri_base))
+               lpfc_set_rrq_active(phba, ndlp, rxid, oxid, 0);
 
        /* Allocate buffer for acc iocb */
        ctiocb = lpfc_sli_get_iocbq(phba);
@@ -11560,6 +12005,7 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
        icmd->ulpLe = 1;
        icmd->ulpClass = CLASS3;
        icmd->ulpContext = ndlp->nlp_rpi;
+       ctiocb->context1 = ndlp;
 
        ctiocb->iocb_cmpl = NULL;
        ctiocb->vport = phba->pport;
@@ -12129,42 +12575,37 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp)
 
 /**
  * lpfc_sli4_init_vpi - Initialize a vpi with the port
- * @phba: pointer to lpfc hba data structure.
- * @vpi: vpi value to activate with the port.
+ * @vport: Pointer to the vport for which the vpi is being initialized
  *
- * This routine is invoked to activate a vpi with the
- * port when the host intends to use vports with a
- * nonzero vpi.
+ * This routine is invoked to activate a vpi with the port.
  *
  * Returns:
  *    0 success
  *    -Evalue otherwise
  **/
 int
-lpfc_sli4_init_vpi(struct lpfc_hba *phba, uint16_t vpi)
+lpfc_sli4_init_vpi(struct lpfc_vport *vport)
 {
        LPFC_MBOXQ_t *mboxq;
        int rc = 0;
        int retval = MBX_SUCCESS;
        uint32_t mbox_tmo;
-
-       if (vpi == 0)
-               return -EINVAL;
+       struct lpfc_hba *phba = vport->phba;
        mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!mboxq)
                return -ENOMEM;
-       lpfc_init_vpi(phba, mboxq, vpi);
+       lpfc_init_vpi(phba, mboxq, vport->vpi);
        mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI);
        rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
        if (rc != MBX_SUCCESS) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_SLI,
                                "2022 INIT VPI Mailbox failed "
                                "status %d, mbxStatus x%x\n", rc,
                                bf_get(lpfc_mqe_status, &mboxq->u.mqe));
                retval = -EIO;
        }
        if (rc != MBX_TIMEOUT)
-               mempool_free(mboxq, phba->mbox_mem_pool);
+               mempool_free(mboxq, vport->phba->mbox_mem_pool);
 
        return retval;
 }
@@ -12854,6 +13295,7 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
        struct lpfc_nodelist *act_mbx_ndlp = NULL;
        struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
        LIST_HEAD(mbox_cmd_list);
+       uint8_t restart_loop;
 
        /* Clean up internally queued mailbox commands with the vport */
        spin_lock_irq(&phba->hbalock);
@@ -12882,15 +13324,44 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
                        mb->mbox_flag |= LPFC_MBX_IMED_UNREG;
                }
        }
+       /* Cleanup any mailbox completions which are not yet processed */
+       do {
+               restart_loop = 0;
+               list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) {
+                       /*
+                        * If this mailox is already processed or it is
+                        * for another vport ignore it.
+                        */
+                       if ((mb->vport != vport) ||
+                               (mb->mbox_flag & LPFC_MBX_IMED_UNREG))
+                               continue;
+
+                       if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) &&
+                               (mb->u.mb.mbxCommand != MBX_REG_VPI))
+                               continue;
+
+                       mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+                       if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
+                               ndlp = (struct lpfc_nodelist *)mb->context2;
+                               /* Unregister the RPI when mailbox complete */
+                               mb->mbox_flag |= LPFC_MBX_IMED_UNREG;
+                               restart_loop = 1;
+                               spin_unlock_irq(&phba->hbalock);
+                               spin_lock(shost->host_lock);
+                               ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
+                               spin_unlock(shost->host_lock);
+                               spin_lock_irq(&phba->hbalock);
+                               break;
+                       }
+               }
+       } while (restart_loop);
+
        spin_unlock_irq(&phba->hbalock);
 
        /* Release the cleaned-up mailbox commands */
        while (!list_empty(&mbox_cmd_list)) {
                list_remove_head(&mbox_cmd_list, mb, LPFC_MBOXQ_t, list);
                if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
-                       if (phba->sli_rev == LPFC_SLI_REV4)
-                               __lpfc_sli4_free_rpi(phba,
-                                               mb->u.mb.un.varRegLogin.rpi);
                        mp = (struct lpfc_dmabuf *) (mb->context1);
                        if (mp) {
                                __lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -12948,12 +13419,13 @@ lpfc_drain_txq(struct lpfc_hba *phba)
        while (pring->txq_cnt) {
                spin_lock_irqsave(&phba->hbalock, iflags);
 
-               sglq = __lpfc_sli_get_sglq(phba);
+               piocbq = lpfc_sli_ringtx_get(phba, pring);
+               sglq = __lpfc_sli_get_sglq(phba, piocbq);
                if (!sglq) {
+                       __lpfc_sli_ringtx_put(phba, pring, piocbq);
                        spin_unlock_irqrestore(&phba->hbalock, iflags);
                        break;
                } else {
-                       piocbq = lpfc_sli_ringtx_get(phba, pring);
                        if (!piocbq) {
                                /* The txq_cnt out of sync. This should
                                 * never happen
index cd56d6cce6c35df54fb0688071e32637b4585f47..453577c21c14b3ef04bfeb3029b875c9269e6ef3 100644 (file)
@@ -34,9 +34,11 @@ struct lpfc_cq_event {
        union {
                struct lpfc_mcqe                mcqe_cmpl;
                struct lpfc_acqe_link           acqe_link;
-               struct lpfc_acqe_fcoe           acqe_fcoe;
+               struct lpfc_acqe_fip            acqe_fip;
                struct lpfc_acqe_dcbx           acqe_dcbx;
                struct lpfc_acqe_grp5           acqe_grp5;
+               struct lpfc_acqe_fc_la          acqe_fc;
+               struct lpfc_acqe_sli            acqe_sli;
                struct lpfc_rcqe                rcqe_cmpl;
                struct sli4_wcqe_xri_aborted    wcqe_axri;
                struct lpfc_wcqe_complete       wcqe_cmpl;
@@ -82,6 +84,7 @@ struct lpfc_iocbq {
                struct lpfc_iocbq    *rsp_iocb;
                struct lpfcMboxq     *mbox;
                struct lpfc_nodelist *ndlp;
+               struct lpfc_node_rrq *rrq;
        } context_un;
 
        void (*fabric_iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
index c4483feb8b71a32a4198175ac91a0c142a647e61..c7217d579e0fa13c4de871bce3fe98088afae187 100644 (file)
@@ -137,9 +137,11 @@ struct lpfc_sli4_link {
        uint8_t speed;
        uint8_t duplex;
        uint8_t status;
-       uint8_t physical;
+       uint8_t type;
+       uint8_t number;
        uint8_t fault;
        uint16_t logical_speed;
+       uint16_t topology;
 };
 
 struct lpfc_fcf_rec {
@@ -367,23 +369,39 @@ struct lpfc_sli4_hba {
                                             PCI BAR1, control registers */
        void __iomem *drbl_regs_memmap_p; /* Kernel memory mapped address for
                                             PCI BAR2, doorbell registers */
-       /* BAR0 PCI config space register memory map */
-       void __iomem *UERRLOregaddr; /* Address to UERR_STATUS_LO register */
-       void __iomem *UERRHIregaddr; /* Address to UERR_STATUS_HI register */
-       void __iomem *UEMASKLOregaddr; /* Address to UE_MASK_LO register */
-       void __iomem *UEMASKHIregaddr; /* Address to UE_MASK_HI register */
-       void __iomem *SLIINTFregaddr; /* Address to SLI_INTF register */
-       /* BAR1 FCoE function CSR register memory map */
-       void __iomem *STAregaddr;    /* Address to HST_STATE register */
-       void __iomem *ISRregaddr;    /* Address to HST_ISR register */
-       void __iomem *IMRregaddr;    /* Address to HST_IMR register */
-       void __iomem *ISCRregaddr;   /* Address to HST_ISCR register */
-       /* BAR2 VF-0 doorbell register memory map */
-       void __iomem *RQDBregaddr;   /* Address to RQ_DOORBELL register */
-       void __iomem *WQDBregaddr;   /* Address to WQ_DOORBELL register */
-       void __iomem *EQCQDBregaddr; /* Address to EQCQ_DOORBELL register */
-       void __iomem *MQDBregaddr;   /* Address to MQ_DOORBELL register */
-       void __iomem *BMBXregaddr;   /* Address to BootStrap MBX register */
+       union {
+               struct {
+                       /* IF Type 0, BAR 0 PCI cfg space reg mem map */
+                       void __iomem *UERRLOregaddr;
+                       void __iomem *UERRHIregaddr;
+                       void __iomem *UEMASKLOregaddr;
+                       void __iomem *UEMASKHIregaddr;
+               } if_type0;
+               struct {
+                       /* IF Type 2, BAR 0 PCI cfg space reg mem map. */
+                       void __iomem *STATUSregaddr;
+                       void __iomem *CTRLregaddr;
+                       void __iomem *ERR1regaddr;
+                       void __iomem *ERR2regaddr;
+               } if_type2;
+       } u;
+
+       /* IF type 0, BAR1 and if type 2, Bar 0 CSR register memory map */
+       void __iomem *PSMPHRregaddr;
+
+       /* Well-known SLI INTF register memory map. */
+       void __iomem *SLIINTFregaddr;
+
+       /* IF type 0, BAR 1 function CSR register memory map */
+       void __iomem *ISRregaddr;       /* HST_ISR register */
+       void __iomem *IMRregaddr;       /* HST_IMR register */
+       void __iomem *ISCRregaddr;      /* HST_ISCR register */
+       /* IF type 0, BAR 0 and if type 2, BAR 0 doorbell register memory map */
+       void __iomem *RQDBregaddr;      /* RQ_DOORBELL register */
+       void __iomem *WQDBregaddr;      /* WQ_DOORBELL register */
+       void __iomem *EQCQDBregaddr;    /* EQCQ_DOORBELL register */
+       void __iomem *MQDBregaddr;      /* MQ_DOORBELL register */
+       void __iomem *BMBXregaddr;      /* BootStrap MBX register */
 
        uint32_t ue_mask_lo;
        uint32_t ue_mask_hi;
@@ -466,6 +484,7 @@ struct lpfc_sglq {
        struct list_head clist;
        enum lpfc_sge_type buff_type; /* is this a scsi sgl */
        enum lpfc_sgl_state state;
+       struct lpfc_nodelist *ndlp; /* ndlp associated with IO */
        uint16_t iotag;         /* pre-assigned IO tag */
        uint16_t sli4_xritag;   /* pre-assigned XRI, (OXID) tag. */
        struct sli4_sge *sgl;   /* pre-assigned SGL */
@@ -532,7 +551,6 @@ int lpfc_sli4_post_all_rpi_hdrs(struct lpfc_hba *);
 struct lpfc_rpi_hdr *lpfc_sli4_create_rpi_hdr(struct lpfc_hba *);
 void lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *);
 int lpfc_sli4_alloc_rpi(struct lpfc_hba *);
-void __lpfc_sli4_free_rpi(struct lpfc_hba *, int);
 void lpfc_sli4_free_rpi(struct lpfc_hba *, int);
 void lpfc_sli4_remove_rpis(struct lpfc_hba *);
 void lpfc_sli4_async_event_proc(struct lpfc_hba *);
@@ -548,7 +566,7 @@ int lpfc_sli4_brdreset(struct lpfc_hba *);
 int lpfc_sli4_add_fcf_record(struct lpfc_hba *, struct fcf_record *);
 void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *);
 int lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *);
-int lpfc_sli4_init_vpi(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_init_vpi(struct lpfc_vport *);
 uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool);
 uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool);
 void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t);
index 7a1b5b112a0bca1c26481063875576430a7ac664..386cf92de49236926146706813f2106647362e66 100644 (file)
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.18"
+#define LPFC_DRIVER_VERSION "8.3.20"
 #define LPFC_DRIVER_NAME               "lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME    "lpfc:sp"
 #define LPFC_FP_DRIVER_HANDLER_NAME    "lpfc:fp"
index a5281ce893d0fb4181710df0f7c3cf19b1f81e04..6b8d2952e32f2a284d1fe4222f7dd26e49323733 100644 (file)
@@ -395,8 +395,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
         * by the port.
         */
        if ((phba->sli_rev == LPFC_SLI_REV4) &&
-               (pport->fc_flag & FC_VFI_REGISTERED)) {
-               rc = lpfc_sli4_init_vpi(phba, vpi);
+           (pport->fc_flag & FC_VFI_REGISTERED)) {
+               rc = lpfc_sli4_init_vpi(vport);
                if (rc) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
                                        "1838 Failed to INIT_VPI on vpi %d "
@@ -418,7 +418,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
 
        if ((phba->link_state < LPFC_LINK_UP) ||
            (pport->port_state < LPFC_FABRIC_CFG_LINK) ||
-           (phba->fc_topology == TOPOLOGY_LOOP)) {
+           (phba->fc_topology == LPFC_TOPOLOGY_LOOP)) {
                lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
                rc = VPORT_OK;
                goto out;
@@ -514,7 +514,7 @@ enable_vport(struct fc_vport *fc_vport)
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 
        if ((phba->link_state < LPFC_LINK_UP) ||
-           (phba->fc_topology == TOPOLOGY_LOOP)) {
+           (phba->fc_topology == LPFC_TOPOLOGY_LOOP)) {
                lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
                return VPORT_OK;
        }
@@ -665,7 +665,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
        if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
            ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
            phba->link_state >= LPFC_LINK_UP &&
-           phba->fc_topology != TOPOLOGY_LOOP) {
+           phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
                if (vport->cfg_enable_da_id) {
                        timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
                        if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0))
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 f469915b97c388833d5c0d5d2b844bf84fb5526a..5826ed509e3e69db5ca648e9bbbcdcf3758c9042 100644 (file)
@@ -1,3 +1,5 @@
 obj-$(CONFIG_MEGARAID_MM)      += megaraid_mm.o
 obj-$(CONFIG_MEGARAID_MAILBOX) += megaraid_mbox.o
 obj-$(CONFIG_MEGARAID_SAS)     += megaraid_sas.o
+megaraid_sas-objs := megaraid_sas_base.o megaraid_sas_fusion.o \
+       megaraid_sas_fp.o
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 ad16f5e600462955bec5c5e4878119a4093f1ae7..1b5e375732c01c7d97486e9e47f108a0982fcf29 100644 (file)
@@ -1,15 +1,30 @@
 /*
+ *  Linux MegaRAID driver for SAS based RAID controllers
  *
- *             Linux MegaRAID driver for SAS based RAID controllers
+ *  Copyright (c) 2009-2011  LSI Corporation.
  *
- * Copyright (c) 2003-2005  LSI Corporation.
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
  *
- *             This program is 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.
  *
- * FILE                : megaraid_sas.h
+ *  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
+ *
+ *  FILE: megaraid_sas.h
+ *
+ *  Authors: LSI Corporation
+ *
+ *  Send feedback to: <megaraidlinux@lsi.com>
+ *
+ *  Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ *     ATTN: Linuxraid
  */
 
 #ifndef LSI_MEGARAID_SAS_H
@@ -18,9 +33,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                        "00.00.04.31-rc1"
-#define MEGASAS_RELDATE                        "May 3, 2010"
-#define MEGASAS_EXT_VERSION            "Mon. May 3, 11:41:51 PST 2010"
+#define MEGASAS_VERSION                                "00.00.05.29-rc1"
+#define MEGASAS_RELDATE                                "Dec. 7, 2010"
+#define MEGASAS_EXT_VERSION                    "Tue. Dec. 7 17:00:00 PDT 2010"
 
 /*
  * Device IDs
@@ -32,6 +47,7 @@
 #define        PCI_DEVICE_ID_LSI_SAS0079GEN2           0x0079
 #define        PCI_DEVICE_ID_LSI_SAS0073SKINNY         0x0073
 #define        PCI_DEVICE_ID_LSI_SAS0071SKINNY         0x0071
+#define        PCI_DEVICE_ID_LSI_FUSION                0x005b
 
 /*
  * =====================================
@@ -421,7 +437,6 @@ struct megasas_ctrl_prop {
        * Add properties that can be controlled by
        * a bit in the following structure.
        */
-
        struct {
                u32     copyBackDisabled            : 1;
                u32     SMARTerEnabled              : 1;
@@ -701,6 +716,7 @@ struct megasas_ctrl_info {
 #define MEGASAS_DEFAULT_INIT_ID                        -1
 #define MEGASAS_MAX_LUN                                8
 #define MEGASAS_MAX_LD                         64
+#define MEGASAS_DEFAULT_CMD_PER_LUN            128
 #define MEGASAS_MAX_PD                          (MEGASAS_MAX_PD_CHANNELS * \
                                                MEGASAS_MAX_DEV_PER_CHANNEL)
 #define MEGASAS_MAX_LD_IDS                     (MEGASAS_MAX_LD_CHANNELS * \
@@ -769,7 +785,10 @@ struct megasas_ctrl_info {
 */
  
 struct megasas_register_set {
-       u32     reserved_0[4];                  /*0000h*/
+       u32     doorbell;                       /*0000h*/
+       u32     fusion_seq_offset;              /*0004h*/
+       u32     fusion_host_diag;               /*0008h*/
+       u32     reserved_01;                    /*000Ch*/
 
        u32     inbound_msg_0;                  /*0010h*/
        u32     inbound_msg_1;                  /*0014h*/
@@ -789,15 +808,18 @@ struct megasas_register_set {
        u32     inbound_queue_port;             /*0040h*/
        u32     outbound_queue_port;            /*0044h*/
 
-       u32     reserved_2[22];                 /*0048h*/
+       u32     reserved_2[9];                  /*0048h*/
+       u32     reply_post_host_index;          /*006Ch*/
+       u32     reserved_2_2[12];               /*0070h*/
 
        u32     outbound_doorbell_clear;        /*00A0h*/
 
        u32     reserved_3[3];                  /*00A4h*/
 
        u32     outbound_scratch_pad ;          /*00B0h*/
+       u32     outbound_scratch_pad_2;         /*00B4h*/
 
-       u32     reserved_4[3];                  /*00B4h*/
+       u32     reserved_4[2];                  /*00B8h*/
 
        u32     inbound_low_queue_port ;        /*00C0h*/
 
@@ -1272,6 +1294,9 @@ struct megasas_instance {
 
        u16 max_num_sge;
        u16 max_fw_cmds;
+       /* For Fusion its num IOCTL cmds, for others MFI based its
+          max_fw_cmds */
+       u16 max_mfi_cmds;
        u32 max_sectors_per_req;
        struct megasas_aen_event *ev;
 
@@ -1320,6 +1345,16 @@ struct megasas_instance {
 
        struct timer_list io_completion_timer;
        struct list_head internal_reset_pending_q;
+
+       /* Ptr to hba specfic information */
+       void *ctrl_context;
+       u8      msi_flag;
+       struct msix_entry msixentry;
+       u64 map_id;
+       struct megasas_cmd *map_update_cmd;
+       unsigned long bar;
+       long reset_flags;
+       struct mutex reset_mutex;
 };
 
 enum {
@@ -1345,6 +1380,13 @@ struct megasas_instance_template {
                struct megasas_register_set __iomem *);
        int (*check_reset)(struct megasas_instance *, \
                struct megasas_register_set __iomem *);
+       irqreturn_t (*service_isr)(int irq, void *devp);
+       void (*tasklet)(unsigned long);
+       u32 (*init_adapter)(struct megasas_instance *);
+       u32 (*build_and_issue_cmd) (struct megasas_instance *,
+                                   struct scsi_cmnd *);
+       void (*issue_dcmd) (struct megasas_instance *instance,
+                           struct megasas_cmd *cmd);
 };
 
 #define MEGASAS_IS_LOGICAL(scp)                                                \
@@ -1371,7 +1413,13 @@ struct megasas_cmd {
        struct list_head list;
        struct scsi_cmnd *scmd;
        struct megasas_instance *instance;
-       u32 frame_count;
+       union {
+               struct {
+                       u16 smid;
+                       u16 resvd;
+               } context;
+               u32 frame_count;
+       };
 };
 
 #define MAX_MGMT_ADAPTERS              1024
similarity index 89%
rename from drivers/scsi/megaraid/megaraid_sas.c
rename to drivers/scsi/megaraid/megaraid_sas_base.c
index eb29d508513148653fb492df24cee9ab0b14cb17..5d6d07bd1cd0565f0c89b004e494d1d15c06a8a7 100644 (file)
@@ -1,27 +1,34 @@
 /*
+ *  Linux MegaRAID driver for SAS based RAID controllers
  *
- *             Linux MegaRAID driver for SAS based RAID controllers
+ *  Copyright (c) 2009-2011  LSI Corporation.
  *
- * Copyright (c) 2003-2005  LSI Corporation.
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
  *
- *        This program is 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.
  *
- * FILE                : megaraid_sas.c
- * Version     : v00.00.04.31-rc1
+ *  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
  *
- * Authors:
- *     (email-id : megaraidlinux@lsi.com)
- *     Sreenivas Bagalkote
- *     Sumant Patro
- *     Bo Yang
+ *  FILE: megaraid_sas_base.c
+ *  Version : v00.00.05.29-rc1
  *
- * List of supported controllers
+ *  Authors: LSI Corporation
+ *           Sreenivas Bagalkote
+ *           Sumant Patro
+ *           Bo Yang
  *
- * OEM Product Name                    VID     DID     SSVID   SSID
- * --- ------------                    ---     ---     ----    ----
+ *  Send feedback to: <megaraidlinux@lsi.com>
+ *
+ *  Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ *     ATTN: Linuxraid
  */
 
 #include <linux/kernel.h>
@@ -46,6 +53,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
+#include "megaraid_sas_fusion.h"
 #include "megaraid_sas.h"
 
 /*
@@ -65,12 +73,16 @@ module_param_named(max_sectors, max_sectors, int, 0);
 MODULE_PARM_DESC(max_sectors,
        "Maximum number of sectors per IO command");
 
+static int msix_disable;
+module_param(msix_disable, int, S_IRUGO);
+MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0");
+
 MODULE_LICENSE("GPL");
 MODULE_VERSION(MEGASAS_VERSION);
 MODULE_AUTHOR("megaraidlinux@lsi.com");
 MODULE_DESCRIPTION("LSI MegaRAID SAS Driver");
 
-static int megasas_transition_to_ready(struct megasas_instance *instance);
+int megasas_transition_to_ready(struct megasas_instance *instance);
 static int megasas_get_pd_list(struct megasas_instance *instance);
 static int megasas_issue_init_mfi(struct megasas_instance *instance);
 static int megasas_register_aen(struct megasas_instance *instance,
@@ -98,6 +110,8 @@ static struct pci_device_id megasas_pci_table[] = {
        /* xscale IOP, vega */
        {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
        /* xscale IOP */
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)},
+       /* Fusion */
        {}
 };
 
@@ -111,23 +125,55 @@ static DEFINE_MUTEX(megasas_async_queue_mutex);
 static int megasas_poll_wait_aen;
 static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
 static u32 support_poll_for_event;
-static u32 megasas_dbg_lvl;
+u32 megasas_dbg_lvl;
 static u32 support_device_change;
 
 /* define lock for aen poll */
 spinlock_t poll_aen_lock;
 
-static void
+void
 megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
                     u8 alt_status);
 
+static irqreturn_t megasas_isr(int irq, void *devp);
+static u32
+megasas_init_adapter_mfi(struct megasas_instance *instance);
+u32
+megasas_build_and_issue_cmd(struct megasas_instance *instance,
+                           struct scsi_cmnd *scmd);
+static void megasas_complete_cmd_dpc(unsigned long instance_addr);
+void
+megasas_release_fusion(struct megasas_instance *instance);
+int
+megasas_ioc_init_fusion(struct megasas_instance *instance);
+void
+megasas_free_cmds_fusion(struct megasas_instance *instance);
+u8
+megasas_get_map_info(struct megasas_instance *instance);
+int
+megasas_sync_map_info(struct megasas_instance *instance);
+int
+wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd);
+void megasas_reset_reply_desc(struct megasas_instance *instance);
+u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
+                     struct LD_LOAD_BALANCE_INFO *lbInfo);
+int megasas_reset_fusion(struct Scsi_Host *shost);
+void megasas_fusion_ocr_wq(struct work_struct *work);
+
+void
+megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+       instance->instancet->fire_cmd(instance,
+               cmd->frame_phys_addr, 0, instance->reg_set);
+}
+
 /**
  * megasas_get_cmd -   Get a command from the free pool
  * @instance:          Adapter soft state
  *
  * Returns a free command from the pool
  */
-static struct megasas_cmd *megasas_get_cmd(struct megasas_instance
+struct megasas_cmd *megasas_get_cmd(struct megasas_instance
                                                  *instance)
 {
        unsigned long flags;
@@ -152,7 +198,7 @@ static struct megasas_cmd *megasas_get_cmd(struct megasas_instance
  * @instance:          Adapter soft state
  * @cmd:               Command packet to be returned to free command pool
  */
-static inline void
+inline void
 megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
        unsigned long flags;
@@ -160,6 +206,7 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
        spin_lock_irqsave(&instance->cmd_pool_lock, flags);
 
        cmd->scmd = NULL;
+       cmd->frame_count = 0;
        list_add_tail(&cmd->list, &instance->cmd_pool);
 
        spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
@@ -167,7 +214,7 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
 
 
 /**
-*      The following functions are defined for xscale 
+*      The following functions are defined for xscale
 *      (deviceid : 1064R, PERC5) controllers
 */
 
@@ -210,7 +257,7 @@ megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
  * megasas_clear_interrupt_xscale -    Check & clear interrupt
  * @regs:                              MFI register set
  */
-static int 
+static int
 megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
 {
        u32 status;
@@ -243,7 +290,7 @@ megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
  * @frame_count :              Number of frames for the command
  * @regs :                     MFI register set
  */
-static inline void 
+static inline void
 megasas_fire_cmd_xscale(struct megasas_instance *instance,
                dma_addr_t frame_phys_addr,
                u32 frame_count,
@@ -323,15 +370,20 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
        .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
        .adp_reset = megasas_adp_reset_xscale,
        .check_reset = megasas_check_reset_xscale,
+       .service_isr = megasas_isr,
+       .tasklet = megasas_complete_cmd_dpc,
+       .init_adapter = megasas_init_adapter_mfi,
+       .build_and_issue_cmd = megasas_build_and_issue_cmd,
+       .issue_dcmd = megasas_issue_dcmd,
 };
 
 /**
-*      This is the end of set of functions & definitions specific 
+*      This is the end of set of functions & definitions specific
 *      to xscale (deviceid : 1064R, PERC5) controllers
 */
 
 /**
-*      The following functions are defined for ppc (deviceid : 0x60) 
+*      The following functions are defined for ppc (deviceid : 0x60)
 *      controllers
 */
 
@@ -343,7 +395,7 @@ static inline void
 megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
 {
        writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
-    
+
        writel(~0x80000000, &(regs)->outbound_intr_mask);
 
        /* Dummy readl to force pci flush */
@@ -377,7 +429,7 @@ megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
  * megasas_clear_interrupt_ppc -       Check & clear interrupt
  * @regs:                              MFI register set
  */
-static int 
+static int
 megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
 {
        u32 status;
@@ -406,7 +458,7 @@ megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
  * @frame_count :              Number of frames for the command
  * @regs :                     MFI register set
  */
-static inline void 
+static inline void
 megasas_fire_cmd_ppc(struct megasas_instance *instance,
                dma_addr_t frame_phys_addr,
                u32 frame_count,
@@ -414,7 +466,7 @@ megasas_fire_cmd_ppc(struct megasas_instance *instance,
 {
        unsigned long flags;
        spin_lock_irqsave(&instance->hba_lock, flags);
-       writel((frame_phys_addr | (frame_count<<1))|1, 
+       writel((frame_phys_addr | (frame_count<<1))|1,
                        &(regs)->inbound_queue_port);
        spin_unlock_irqrestore(&instance->hba_lock, flags);
 }
@@ -441,7 +493,7 @@ megasas_check_reset_ppc(struct megasas_instance *instance,
        return 0;
 }
 static struct megasas_instance_template megasas_instance_template_ppc = {
-       
+
        .fire_cmd = megasas_fire_cmd_ppc,
        .enable_intr = megasas_enable_intr_ppc,
        .disable_intr = megasas_disable_intr_ppc,
@@ -449,6 +501,11 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
        .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
        .adp_reset = megasas_adp_reset_ppc,
        .check_reset = megasas_check_reset_ppc,
+       .service_isr = megasas_isr,
+       .tasklet = megasas_complete_cmd_dpc,
+       .init_adapter = megasas_init_adapter_mfi,
+       .build_and_issue_cmd = megasas_build_and_issue_cmd,
+       .issue_dcmd = megasas_issue_dcmd,
 };
 
 /**
@@ -570,6 +627,11 @@ static struct megasas_instance_template megasas_instance_template_skinny = {
        .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
        .adp_reset = megasas_adp_reset_skinny,
        .check_reset = megasas_check_reset_skinny,
+       .service_isr = megasas_isr,
+       .tasklet = megasas_complete_cmd_dpc,
+       .init_adapter = megasas_init_adapter_mfi,
+       .build_and_issue_cmd = megasas_build_and_issue_cmd,
+       .issue_dcmd = megasas_issue_dcmd,
 };
 
 
@@ -744,6 +806,11 @@ static struct megasas_instance_template megasas_instance_template_gen2 = {
        .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
        .adp_reset = megasas_adp_reset_gen2,
        .check_reset = megasas_check_reset_gen2,
+       .service_isr = megasas_isr,
+       .tasklet = megasas_complete_cmd_dpc,
+       .init_adapter = megasas_init_adapter_mfi,
+       .build_and_issue_cmd = megasas_build_and_issue_cmd,
+       .issue_dcmd = megasas_issue_dcmd,
 };
 
 /**
@@ -751,18 +818,21 @@ static struct megasas_instance_template megasas_instance_template_gen2 = {
 *       specific to gen2 (deviceid : 0x78, 0x79) controllers
 */
 
+/*
+ * Template added for TB (Fusion)
+ */
+extern struct megasas_instance_template megasas_instance_template_fusion;
+
 /**
  * megasas_issue_polled -      Issues a polling command
  * @instance:                  Adapter soft state
- * @cmd:                       Command packet to be issued 
+ * @cmd:                       Command packet to be issued
  *
  * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
  */
-static int
+int
 megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
-       int i;
-       u32 msecs = MFI_POLL_TIMEOUT_SECS * 1000;
 
        struct megasas_header *frame_hdr = &cmd->frame->hdr;
 
@@ -772,21 +842,12 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
        /*
         * Issue the frame using inbound queue port
         */
-       instance->instancet->fire_cmd(instance,
-                       cmd->frame_phys_addr, 0, instance->reg_set);
+       instance->instancet->issue_dcmd(instance, cmd);
 
        /*
         * Wait for cmd_status to change
         */
-       for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i++) {
-               rmb();
-               msleep(1);
-       }
-
-       if (frame_hdr->cmd_status == 0xff)
-               return -ETIME;
-
-       return 0;
+       return wait_and_poll(instance, cmd);
 }
 
 /**
@@ -804,8 +865,7 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
 {
        cmd->cmd_status = ENODATA;
 
-       instance->instancet->fire_cmd(instance,
-                       cmd->frame_phys_addr, 0, instance->reg_set);
+       instance->instancet->issue_dcmd(instance, cmd);
 
        wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA);
 
@@ -849,8 +909,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
        cmd->sync_cmd = 1;
        cmd->cmd_status = 0xFF;
 
-       instance->instancet->fire_cmd(instance,
-                       cmd->frame_phys_addr, 0, instance->reg_set);
+       instance->instancet->issue_dcmd(instance, cmd);
 
        /*
         * Wait for this cmd to complete
@@ -1242,11 +1301,11 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
 /**
  * megasas_is_ldio -           Checks if the cmd is for logical drive
  * @scmd:                      SCSI command
- *     
+ *
  * Called by megasas_queue_command to find out if the command to be queued
- * is a logical drive command  
+ * is a logical drive command
  */
-static inline int megasas_is_ldio(struct scsi_cmnd *cmd)
+inline int megasas_is_ldio(struct scsi_cmnd *cmd)
 {
        if (!MEGASAS_IS_LOGICAL(cmd))
                return 0;
@@ -1328,16 +1387,59 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
        printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
 }
 
+u32
+megasas_build_and_issue_cmd(struct megasas_instance *instance,
+                           struct scsi_cmnd *scmd)
+{
+       struct megasas_cmd *cmd;
+       u32 frame_count;
+
+       cmd = megasas_get_cmd(instance);
+       if (!cmd)
+               return SCSI_MLQUEUE_HOST_BUSY;
+
+       /*
+        * Logical drive command
+        */
+       if (megasas_is_ldio(scmd))
+               frame_count = megasas_build_ldio(instance, scmd, cmd);
+       else
+               frame_count = megasas_build_dcdb(instance, scmd, cmd);
+
+       if (!frame_count)
+               goto out_return_cmd;
+
+       cmd->scmd = scmd;
+       scmd->SCp.ptr = (char *)cmd;
+
+       /*
+        * Issue the command to the FW
+        */
+       atomic_inc(&instance->fw_outstanding);
+
+       instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
+                               cmd->frame_count-1, instance->reg_set);
+       /*
+        * Check if we have pend cmds to be completed
+        */
+       if (poll_mode_io && atomic_read(&instance->fw_outstanding))
+               tasklet_schedule(&instance->isr_tasklet);
+
+       return 0;
+out_return_cmd:
+       megasas_return_cmd(instance, cmd);
+       return 1;
+}
+
+
 /**
  * megasas_queue_command -     Queue entry point
  * @scmd:                      SCSI command to be queued
  * @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;
        struct megasas_instance *instance;
        unsigned long flags;
 
@@ -1376,47 +1478,20 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
                break;
        }
 
-       cmd = megasas_get_cmd(instance);
-       if (!cmd)
+       if (instance->instancet->build_and_issue_cmd(instance, scmd)) {
+               printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n");
                return SCSI_MLQUEUE_HOST_BUSY;
-
-       /*
-        * Logical drive command
-        */
-       if (megasas_is_ldio(scmd))
-               frame_count = megasas_build_ldio(instance, scmd, cmd);
-       else
-               frame_count = megasas_build_dcdb(instance, scmd, cmd);
-
-       if (!frame_count)
-               goto out_return_cmd;
-
-       cmd->scmd = scmd;
-       scmd->SCp.ptr = (char *)cmd;
-
-       /*
-        * Issue the command to the FW
-        */
-       atomic_inc(&instance->fw_outstanding);
-
-       instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
-                               cmd->frame_count-1, instance->reg_set);
-       /*
-        * Check if we have pend cmds to be completed
-        */
-       if (poll_mode_io && atomic_read(&instance->fw_outstanding))
-               tasklet_schedule(&instance->isr_tasklet);
-
+       }
 
        return 0;
 
- out_return_cmd:
-       megasas_return_cmd(instance, cmd);
  out_done:
        done(scmd);
        return 0;
 }
 
+static DEF_SCSI_QCMD(megasas_queue_command)
+
 static struct megasas_instance *megasas_lookup_instance(u16 host_no)
 {
        int i;
@@ -1490,15 +1565,44 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
        return 0;
 }
 
-static void megaraid_sas_kill_hba(struct megasas_instance *instance)
+void megaraid_sas_kill_hba(struct megasas_instance *instance)
 {
        if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
-               writel(MFI_STOP_ADP,
-                       &instance->reg_set->reserved_0[0]);
+           (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+           (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION)) {
+               writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
        } else {
-               writel(MFI_STOP_ADP,
-                       &instance->reg_set->inbound_doorbell);
+               writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell);
+       }
+}
+
+ /**
+  * megasas_check_and_restore_queue_depth - Check if queue depth needs to be
+  *                                    restored to max value
+  * @instance:                 Adapter soft state
+  *
+  */
+void
+megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
+{
+       unsigned long flags;
+       if (instance->flag & MEGASAS_FW_BUSY
+               && time_after(jiffies, instance->last_time + 5 * HZ)
+               && atomic_read(&instance->fw_outstanding) < 17) {
+
+               spin_lock_irqsave(instance->host->host_lock, flags);
+               instance->flag &= ~MEGASAS_FW_BUSY;
+               if ((instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                       (instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                       instance->host->can_queue =
+                               instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+               } else
+                       instance->host->can_queue =
+                               instance->max_fw_cmds - MEGASAS_INT_CMDS;
+
+               spin_unlock_irqrestore(instance->host->host_lock, flags);
        }
 }
 
@@ -1552,24 +1656,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
        /*
         * Check if we can restore can_queue
         */
-       if (instance->flag & MEGASAS_FW_BUSY
-               && time_after(jiffies, instance->last_time + 5 * HZ)
-               && atomic_read(&instance->fw_outstanding) < 17) {
-
-               spin_lock_irqsave(instance->host->host_lock, flags);
-               instance->flag &= ~MEGASAS_FW_BUSY;
-               if ((instance->pdev->device ==
-                       PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-                       (instance->pdev->device ==
-                       PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
-                       instance->host->can_queue =
-                               instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
-               } else
-                       instance->host->can_queue =
-                               instance->max_fw_cmds - MEGASAS_INT_CMDS;
-
-               spin_unlock_irqrestore(instance->host->host_lock, flags);
-       }
+       megasas_check_and_restore_queue_depth(instance);
 }
 
 static void
@@ -1747,7 +1834,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
                        (instance->pdev->device ==
                        PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
                        writel(MFI_STOP_ADP,
-                               &instance->reg_set->reserved_0[0]);
+                               &instance->reg_set->doorbell);
                } else {
                        writel(MFI_STOP_ADP,
                                &instance->reg_set->inbound_doorbell);
@@ -1851,11 +1938,16 @@ static int megasas_reset_device(struct scsi_cmnd *scmd)
 static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
 {
        int ret;
+       struct megasas_instance *instance;
+       instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
        /*
         * First wait for all commands to complete
         */
-       ret = megasas_generic_reset(scmd);
+       if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION)
+               ret = megasas_reset_fusion(scmd->device->host);
+       else
+               ret = megasas_generic_reset(scmd);
 
        return ret;
 }
@@ -1998,8 +2090,8 @@ megasas_complete_int_cmd(struct megasas_instance *instance,
  * @instance:                  Adapter soft state
  * @cmd:                       Cmd that was issued to abort another cmd
  *
- * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q 
- * after it issues an abort on a previously issued command. This function 
+ * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q
+ * after it issues an abort on a previously issued command. This function
  * wakes up all functions waiting on the same wait queue.
  */
 static void
@@ -2019,19 +2111,20 @@ megasas_complete_abort(struct megasas_instance *instance,
  * megasas_complete_cmd -      Completes a command
  * @instance:                  Adapter soft state
  * @cmd:                       Command to be completed
- * @alt_status:                        If non-zero, use this value as status to 
+ * @alt_status:                        If non-zero, use this value as status to
  *                             SCSI mid-layer instead of the value returned
  *                             by the FW. This should be used if caller wants
  *                             an alternate status (as in the case of aborted
  *                             commands)
  */
-static void
+void
 megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
                     u8 alt_status)
 {
        int exception = 0;
        struct megasas_header *hdr = &cmd->frame->hdr;
        unsigned long flags;
+       struct fusion_context *fusion = instance->ctrl_context;
 
        /* flag for the retry reset */
        cmd->retry_for_fw_reset = 0;
@@ -2124,6 +2217,37 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
        case MFI_CMD_SMP:
        case MFI_CMD_STP:
        case MFI_CMD_DCMD:
+               /* Check for LD map update */
+               if ((cmd->frame->dcmd.opcode == MR_DCMD_LD_MAP_GET_INFO) &&
+                   (cmd->frame->dcmd.mbox.b[1] == 1)) {
+                       spin_lock_irqsave(instance->host->host_lock, flags);
+                       if (cmd->frame->hdr.cmd_status != 0) {
+                               if (cmd->frame->hdr.cmd_status !=
+                                   MFI_STAT_NOT_FOUND)
+                                       printk(KERN_WARNING "megasas: map sync"
+                                              "failed, status = 0x%x.\n",
+                                              cmd->frame->hdr.cmd_status);
+                               else {
+                                       megasas_return_cmd(instance, cmd);
+                                       spin_unlock_irqrestore(
+                                               instance->host->host_lock,
+                                               flags);
+                                       break;
+                               }
+                       } else
+                               instance->map_id++;
+                       megasas_return_cmd(instance, cmd);
+                       if (MR_ValidateMapInfo(
+                                   fusion->ld_map[(instance->map_id & 1)],
+                                   fusion->load_balance_info))
+                               fusion->fast_path_io = 1;
+                       else
+                               fusion->fast_path_io = 0;
+                       megasas_sync_map_info(instance);
+                       spin_unlock_irqrestore(instance->host->host_lock,
+                                              flags);
+                       break;
+               }
                if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
                        cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
                        spin_lock_irqsave(&poll_aen_lock, flags);
@@ -2462,7 +2586,7 @@ static irqreturn_t megasas_isr(int irq, void *devp)
  * states, driver must take steps to bring it to ready state. Otherwise, it
  * has to wait for the ready state.
  */
-static int
+int
 megasas_transition_to_ready(struct megasas_instance* instance)
 {
        int i;
@@ -2474,8 +2598,8 @@ megasas_transition_to_ready(struct megasas_instance* instance)
        fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
 
        if (fw_state != MFI_STATE_READY)
-               printk(KERN_INFO "megasas: Waiting for FW to come to ready"
-                      " state\n");
+               printk(KERN_INFO "megasas: Waiting for FW to come to ready"
+                      " state\n");
 
        while (fw_state != MFI_STATE_READY) {
 
@@ -2496,11 +2620,12 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        if ((instance->pdev->device ==
                                PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                                (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
-
+                                PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+                               (instance->pdev->device ==
+                                PCI_DEVICE_ID_LSI_FUSION)) {
                                writel(
                                  MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
-                                 &instance->reg_set->reserved_0[0]);
+                                 &instance->reg_set->doorbell);
                        } else {
                                writel(
                                    MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
@@ -2513,11 +2638,13 @@ megasas_transition_to_ready(struct megasas_instance* instance)
 
                case MFI_STATE_BOOT_MESSAGE_PENDING:
                        if ((instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-                       (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                            PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                               (instance->pdev->device ==
+                                PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+                           (instance->pdev->device ==
+                            PCI_DEVICE_ID_LSI_FUSION)) {
                                writel(MFI_INIT_HOTPLUG,
-                               &instance->reg_set->reserved_0[0]);
+                                      &instance->reg_set->doorbell);
                        } else
                                writel(MFI_INIT_HOTPLUG,
                                        &instance->reg_set->inbound_doorbell);
@@ -2534,9 +2661,23 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        if ((instance->pdev->device ==
                                PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                                (instance->pdev->device ==
-                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)  ||
+                               (instance->pdev->device
+                                       == PCI_DEVICE_ID_LSI_FUSION)) {
                                writel(MFI_RESET_FLAGS,
-                                       &instance->reg_set->reserved_0[0]);
+                                       &instance->reg_set->doorbell);
+                               if (instance->pdev->device ==
+                                   PCI_DEVICE_ID_LSI_FUSION) {
+                                       for (i = 0; i < (10 * 1000); i += 20) {
+                                               if (readl(
+                                                           &instance->
+                                                           reg_set->
+                                                           doorbell) & 1)
+                                                       msleep(20);
+                                               else
+                                                       break;
+                                       }
+                               }
                        } else
                                writel(MFI_RESET_FLAGS,
                                        &instance->reg_set->inbound_doorbell);
@@ -2588,7 +2729,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                 * The cur_state should not last for more than max_wait secs
                 */
                for (i = 0; i < (max_wait * 1000); i++) {
-                       fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &  
+                       fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
                                        MFI_STATE_MASK ;
                curr_abs_state =
                instance->instancet->read_fw_status_reg(instance->reg_set);
@@ -2608,7 +2749,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        return -ENODEV;
                }
        }
-       printk(KERN_INFO "megasas: FW now in Ready state\n");
+       printk(KERN_INFO "megasas: FW now in Ready state\n");
 
        return 0;
 }
@@ -2620,7 +2761,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
 static void megasas_teardown_frame_pool(struct megasas_instance *instance)
 {
        int i;
-       u32 max_cmd = instance->max_fw_cmds;
+       u32 max_cmd = instance->max_mfi_cmds;
        struct megasas_cmd *cmd;
 
        if (!instance->frame_dma_pool)
@@ -2671,7 +2812,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
        u32 frame_count;
        struct megasas_cmd *cmd;
 
-       max_cmd = instance->max_fw_cmds;
+       max_cmd = instance->max_mfi_cmds;
 
        /*
         * Size of our frame is 64 bytes for MFI frame, followed by max SG
@@ -2758,14 +2899,15 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
  * megasas_free_cmds - Free all the cmds in the free cmd pool
  * @instance:          Adapter soft state
  */
-static void megasas_free_cmds(struct megasas_instance *instance)
+void megasas_free_cmds(struct megasas_instance *instance)
 {
        int i;
        /* First free the MFI frame pool */
        megasas_teardown_frame_pool(instance);
 
        /* Free all the commands in the cmd_list */
-       for (i = 0; i < instance->max_fw_cmds; i++)
+       for (i = 0; i < instance->max_mfi_cmds; i++)
+
                kfree(instance->cmd_list[i]);
 
        /* Free the cmd_list buffer itself */
@@ -2793,14 +2935,14 @@ static void megasas_free_cmds(struct megasas_instance *instance)
  * This array is used only to look up the megasas_cmd given the context. The
  * free commands themselves are maintained in a linked list called cmd_pool.
  */
-static int megasas_alloc_cmds(struct megasas_instance *instance)
+int megasas_alloc_cmds(struct megasas_instance *instance)
 {
        int i;
        int j;
        u32 max_cmd;
        struct megasas_cmd *cmd;
 
-       max_cmd = instance->max_fw_cmds;
+       max_cmd = instance->max_mfi_cmds;
 
        /*
         * instance->cmd_list is an array of struct megasas_cmd pointers.
@@ -2814,6 +2956,7 @@ static int megasas_alloc_cmds(struct megasas_instance *instance)
                return -ENOMEM;
        }
 
+       memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) *max_cmd);
 
        for (i = 0; i < max_cmd; i++) {
                instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd),
@@ -3208,76 +3351,15 @@ megasas_io_completion_timer(unsigned long instance_addr)
                        jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL);
 }
 
-/**
- * megasas_init_mfi -  Initializes the FW
- * @instance:          Adapter soft state
- *
- * This is the main function for initializing MFI firmware.
- */
-static int megasas_init_mfi(struct megasas_instance *instance)
+static u32
+megasas_init_adapter_mfi(struct megasas_instance *instance)
 {
+       struct megasas_register_set __iomem *reg_set;
        u32 context_sz;
        u32 reply_q_sz;
-       u32 max_sectors_1;
-       u32 max_sectors_2;
-       u32 tmp_sectors;
-       struct megasas_register_set __iomem *reg_set;
-       struct megasas_ctrl_info *ctrl_info;
-       /*
-        * Map the message registers
-        */
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
-               instance->base_addr = pci_resource_start(instance->pdev, 1);
-       } else {
-               instance->base_addr = pci_resource_start(instance->pdev, 0);
-       }
-
-       if (pci_request_selected_regions(instance->pdev,
-               pci_select_bars(instance->pdev, IORESOURCE_MEM),
-               "megasas: LSI")) {
-               printk(KERN_DEBUG "megasas: IO memory region busy!\n");
-               return -EBUSY;
-       }
-
-       instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
-
-       if (!instance->reg_set) {
-               printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
-               goto fail_ioremap;
-       }
 
        reg_set = instance->reg_set;
 
-       switch(instance->pdev->device)
-       {
-               case PCI_DEVICE_ID_LSI_SAS1078R:
-               case PCI_DEVICE_ID_LSI_SAS1078DE:
-                       instance->instancet = &megasas_instance_template_ppc;
-                       break;
-               case PCI_DEVICE_ID_LSI_SAS1078GEN2:
-               case PCI_DEVICE_ID_LSI_SAS0079GEN2:
-                       instance->instancet = &megasas_instance_template_gen2;
-                       break;
-               case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
-               case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
-                       instance->instancet = &megasas_instance_template_skinny;
-                       break;
-               case PCI_DEVICE_ID_LSI_SAS1064R:
-               case PCI_DEVICE_ID_DELL_PERC5:
-               default:
-                       instance->instancet = &megasas_instance_template_xscale;
-                       break;
-       }
-
-       /*
-        * We expect the FW state to be READY
-        */
-       if (megasas_transition_to_ready(instance))
-               goto fail_ready_state;
-
        /*
         * Get various operational parameters from status register
         */
@@ -3288,7 +3370,8 @@ static int megasas_init_mfi(struct megasas_instance *instance)
         * does not exceed max cmds that the FW can support
         */
        instance->max_fw_cmds = instance->max_fw_cmds-1;
-       instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 
+       instance->max_mfi_cmds = instance->max_fw_cmds;
+       instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
                                        0x10;
        /*
         * Create a pool of commands
@@ -3331,6 +3414,90 @@ static int megasas_init_mfi(struct megasas_instance *instance)
        if (instance->fw_support_ieee)
                instance->flag_ieee = 1;
 
+       return 0;
+
+fail_fw_init:
+
+       pci_free_consistent(instance->pdev, reply_q_sz,
+                           instance->reply_queue, instance->reply_queue_h);
+fail_reply_queue:
+       megasas_free_cmds(instance);
+
+fail_alloc_cmds:
+       iounmap(instance->reg_set);
+       return 1;
+}
+
+/**
+ * megasas_init_fw -   Initializes the FW
+ * @instance:          Adapter soft state
+ *
+ * This is the main function for initializing firmware
+ */
+
+static int megasas_init_fw(struct megasas_instance *instance)
+{
+       u32 max_sectors_1;
+       u32 max_sectors_2;
+       u32 tmp_sectors;
+       struct megasas_register_set __iomem *reg_set;
+       struct megasas_ctrl_info *ctrl_info;
+       unsigned long bar_list;
+
+       /* Find first memory bar */
+       bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
+       instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
+       instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
+       if (pci_request_selected_regions(instance->pdev, instance->bar,
+                                        "megasas: LSI")) {
+               printk(KERN_DEBUG "megasas: IO memory region busy!\n");
+               return -EBUSY;
+       }
+
+       instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
+
+       if (!instance->reg_set) {
+               printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
+               goto fail_ioremap;
+       }
+
+       reg_set = instance->reg_set;
+
+       switch (instance->pdev->device) {
+       case PCI_DEVICE_ID_LSI_FUSION:
+               instance->instancet = &megasas_instance_template_fusion;
+               break;
+       case PCI_DEVICE_ID_LSI_SAS1078R:
+       case PCI_DEVICE_ID_LSI_SAS1078DE:
+               instance->instancet = &megasas_instance_template_ppc;
+               break;
+       case PCI_DEVICE_ID_LSI_SAS1078GEN2:
+       case PCI_DEVICE_ID_LSI_SAS0079GEN2:
+               instance->instancet = &megasas_instance_template_gen2;
+               break;
+       case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
+       case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
+               instance->instancet = &megasas_instance_template_skinny;
+               break;
+       case PCI_DEVICE_ID_LSI_SAS1064R:
+       case PCI_DEVICE_ID_DELL_PERC5:
+       default:
+               instance->instancet = &megasas_instance_template_xscale;
+               break;
+       }
+
+       /*
+        * We expect the FW state to be READY
+        */
+       if (megasas_transition_to_ready(instance))
+               goto fail_ready_state;
+
+       /* Get operational params, sge flags, send init cmd to controller */
+       if (instance->instancet->init_adapter(instance))
+               return -ENODEV;
+
+       printk(KERN_ERR "megasas: INIT adapter done\n");
+
        /** for passthrough
        * the following function will get the PD LIST.
        */
@@ -3386,20 +3553,11 @@ static int megasas_init_mfi(struct megasas_instance *instance)
                                MEGASAS_COMPLETION_TIMER_INTERVAL);
        return 0;
 
-      fail_fw_init:
-
-       pci_free_consistent(instance->pdev, reply_q_sz,
-                           instance->reply_queue, instance->reply_queue_h);
-      fail_reply_queue:
-       megasas_free_cmds(instance);
-
-      fail_alloc_cmds:
-      fail_ready_state:
+fail_ready_state:
        iounmap(instance->reg_set);
 
       fail_ioremap:
-       pci_release_selected_regions(instance->pdev,
-               pci_select_bars(instance->pdev, IORESOURCE_MEM));
+       pci_release_selected_regions(instance->pdev, instance->bar);
 
        return -EINVAL;
 }
@@ -3410,17 +3568,17 @@ static int megasas_init_mfi(struct megasas_instance *instance)
  */
 static void megasas_release_mfi(struct megasas_instance *instance)
 {
-       u32 reply_q_sz = sizeof(u32) * (instance->max_fw_cmds + 1);
+       u32 reply_q_sz = sizeof(u32) *(instance->max_mfi_cmds + 1);
 
-       pci_free_consistent(instance->pdev, reply_q_sz,
+       if (instance->reply_queue)
+               pci_free_consistent(instance->pdev, reply_q_sz,
                            instance->reply_queue, instance->reply_queue_h);
 
        megasas_free_cmds(instance);
 
        iounmap(instance->reg_set);
 
-       pci_release_selected_regions(instance->pdev,
-               pci_select_bars(instance->pdev, IORESOURCE_MEM));
+       pci_release_selected_regions(instance->pdev, instance->bar);
 }
 
 /**
@@ -3607,8 +3765,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
        /*
         * Issue the aen registration frame
         */
-       instance->instancet->fire_cmd(instance,
-                       cmd->frame_phys_addr, 0, instance->reg_set);
+       instance->instancet->issue_dcmd(instance, cmd);
 
        return 0;
 }
@@ -3685,12 +3842,18 @@ static int megasas_io_attach(struct megasas_instance *instance)
        }
 
        host->max_sectors = instance->max_sectors_per_req;
-       host->cmd_per_lun = 128;
+       host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN;
        host->max_channel = MEGASAS_MAX_CHANNELS - 1;
        host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
        host->max_lun = MEGASAS_MAX_LUN;
        host->max_cmd_len = 16;
 
+       /* Fusion only supports host reset */
+       if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) {
+               host->hostt->eh_device_reset_handler = NULL;
+               host->hostt->eh_bus_reset_handler = NULL;
+       }
+
        /*
         * Notify the mid-layer about the new controller
         */
@@ -3731,7 +3894,7 @@ fail_set_dma_mask:
 /**
  * megasas_probe_one - PCI hotplug entry point
  * @pdev:              PCI device structure
- * @id:                        PCI ids of supported hotplugged adapter 
+ * @id:                        PCI ids of supported hotplugged adapter
  */
 static int __devinit
 megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -3775,20 +3938,45 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        instance = (struct megasas_instance *)host->hostdata;
        memset(instance, 0, sizeof(*instance));
        atomic_set( &instance->fw_reset_no_pci_access, 0 );
+       instance->pdev = pdev;
 
-       instance->producer = pci_alloc_consistent(pdev, sizeof(u32),
-                                                 &instance->producer_h);
-       instance->consumer = pci_alloc_consistent(pdev, sizeof(u32),
-                                                 &instance->consumer_h);
+       switch (instance->pdev->device) {
+       case PCI_DEVICE_ID_LSI_FUSION:
+       {
+               struct fusion_context *fusion;
+
+               instance->ctrl_context =
+                       kzalloc(sizeof(struct fusion_context), GFP_KERNEL);
+               if (!instance->ctrl_context) {
+                       printk(KERN_DEBUG "megasas: Failed to allocate "
+                              "memory for Fusion context info\n");
+                       goto fail_alloc_dma_buf;
+               }
+               fusion = instance->ctrl_context;
+               INIT_LIST_HEAD(&fusion->cmd_pool);
+               spin_lock_init(&fusion->cmd_pool_lock);
+       }
+       break;
+       default: /* For all other supported controllers */
+
+               instance->producer =
+                       pci_alloc_consistent(pdev, sizeof(u32),
+                                            &instance->producer_h);
+               instance->consumer =
+                       pci_alloc_consistent(pdev, sizeof(u32),
+                                            &instance->consumer_h);
+
+               if (!instance->producer || !instance->consumer) {
+                       printk(KERN_DEBUG "megasas: Failed to allocate"
+                              "memory for producer, consumer\n");
+                       goto fail_alloc_dma_buf;
+               }
 
-       if (!instance->producer || !instance->consumer) {
-               printk(KERN_DEBUG "megasas: Failed to allocate memory for "
-                      "producer, consumer\n");
-               goto fail_alloc_dma_buf;
+               *instance->producer = 0;
+               *instance->consumer = 0;
+               break;
        }
 
-       *instance->producer = 0;
-       *instance->consumer = 0;
        megasas_poll_wait_aen = 0;
        instance->flag_ieee = 0;
        instance->ev = NULL;
@@ -3824,11 +4012,11 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        spin_lock_init(&poll_aen_lock);
 
        mutex_init(&instance->aen_mutex);
+       mutex_init(&instance->reset_mutex);
 
        /*
         * Initialize PCI related and misc parameters
         */
-       instance->pdev = pdev;
        instance->host = host;
        instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
        instance->init_id = MEGASAS_DEFAULT_INIT_ID;
@@ -3846,18 +4034,31 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        instance->last_time = 0;
        instance->disableOnlineCtrlReset = 1;
 
-       INIT_WORK(&instance->work_init, process_fw_state_change_wq);
+       if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION)
+               INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
+       else
+               INIT_WORK(&instance->work_init, process_fw_state_change_wq);
 
        /*
         * Initialize MFI Firmware
         */
-       if (megasas_init_mfi(instance))
+       if (megasas_init_fw(instance))
                goto fail_init_mfi;
 
+       /* Try to enable MSI-X */
+       if ((instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078R) &&
+           (instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078DE) &&
+           (instance->pdev->device != PCI_DEVICE_ID_LSI_VERDE_ZCR) &&
+           !msix_disable && !pci_enable_msix(instance->pdev,
+                                             &instance->msixentry, 1))
+               instance->msi_flag = 1;
+
        /*
         * Register IRQ
         */
-       if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED, "megasas", instance)) {
+       if (request_irq(instance->msi_flag ? instance->msixentry.vector :
+                       pdev->irq, instance->instancet->service_isr,
+                       IRQF_SHARED, "megasas", instance)) {
                printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
                goto fail_irq;
        }
@@ -3902,9 +4103,10 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        pci_set_drvdata(pdev, NULL);
        instance->instancet->disable_intr(instance->reg_set);
-       free_irq(instance->pdev->irq, instance);
-
-       megasas_release_mfi(instance);
+       free_irq(instance->msi_flag ? instance->msixentry.vector :
+                instance->pdev->irq, instance);
+       if (instance->msi_flag)
+               pci_disable_msix(instance->pdev);
 
       fail_irq:
       fail_init_mfi:
@@ -3914,9 +4116,13 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                                    instance->evt_detail,
                                    instance->evt_detail_h);
 
-       if (instance->producer)
+       if (instance->producer) {
                pci_free_consistent(pdev, sizeof(u32), instance->producer,
                                    instance->producer_h);
+               megasas_release_mfi(instance);
+       } else {
+               megasas_release_fusion(instance);
+       }
        if (instance->consumer)
                pci_free_consistent(pdev, sizeof(u32), instance->consumer,
                                    instance->consumer_h);
@@ -3988,7 +4194,9 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
 
        if (instance->aen_cmd)
                megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd);
-
+       if (instance->map_update_cmd)
+               megasas_issue_blocked_abort_cmd(instance,
+                                               instance->map_update_cmd);
        dcmd = &cmd->frame->dcmd;
 
        memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
@@ -4044,7 +4252,10 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
 
        pci_set_drvdata(instance->pdev, instance);
        instance->instancet->disable_intr(instance->reg_set);
-       free_irq(instance->pdev->irq, instance);
+       free_irq(instance->msi_flag ? instance->msixentry.vector :
+                instance->pdev->irq, instance);
+       if (instance->msi_flag)
+               pci_disable_msix(instance->pdev);
 
        pci_save_state(pdev);
        pci_disable_device(pdev);
@@ -4090,9 +4301,6 @@ megasas_resume(struct pci_dev *pdev)
         * Initialize MFI Firmware
         */
 
-       *instance->producer = 0;
-       *instance->consumer = 0;
-
        atomic_set(&instance->fw_outstanding, 0);
 
        /*
@@ -4101,17 +4309,40 @@ megasas_resume(struct pci_dev *pdev)
        if (megasas_transition_to_ready(instance))
                goto fail_ready_state;
 
-       if (megasas_issue_init_mfi(instance))
-               goto fail_init_mfi;
+       switch (instance->pdev->device) {
+       case PCI_DEVICE_ID_LSI_FUSION:
+       {
+               megasas_reset_reply_desc(instance);
+               if (megasas_ioc_init_fusion(instance)) {
+                       megasas_free_cmds(instance);
+                       megasas_free_cmds_fusion(instance);
+                       goto fail_init_mfi;
+               }
+               if (!megasas_get_map_info(instance))
+                       megasas_sync_map_info(instance);
+       }
+       break;
+       default:
+               *instance->producer = 0;
+               *instance->consumer = 0;
+               if (megasas_issue_init_mfi(instance))
+                       goto fail_init_mfi;
+               break;
+       }
 
-       tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
-                       (unsigned long)instance);
+       tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
+                    (unsigned long)instance);
+
+       /* Now re-enable MSI-X */
+       if (instance->msi_flag)
+               pci_enable_msix(instance->pdev, &instance->msixentry, 1);
 
        /*
         * Register IRQ
         */
-       if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED,
-               "megasas", instance)) {
+       if (request_irq(instance->msi_flag ? instance->msixentry.vector :
+                       pdev->irq, instance->instancet->service_isr,
+                       IRQF_SHARED, "megasas", instance)) {
                printk(KERN_ERR "megasas: Failed to register IRQ\n");
                goto fail_irq;
        }
@@ -4169,10 +4400,12 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
        int i;
        struct Scsi_Host *host;
        struct megasas_instance *instance;
+       struct fusion_context *fusion;
 
        instance = pci_get_drvdata(pdev);
        instance->unload = 1;
        host = instance->host;
+       fusion = instance->ctrl_context;
 
        if (poll_mode_io)
                del_timer_sync(&instance->io_completion_timer);
@@ -4209,18 +4442,37 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
 
        instance->instancet->disable_intr(instance->reg_set);
 
-       free_irq(instance->pdev->irq, instance);
-
-       megasas_release_mfi(instance);
-
-       pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
-                           instance->evt_detail, instance->evt_detail_h);
-
-       pci_free_consistent(pdev, sizeof(u32), instance->producer,
-                           instance->producer_h);
-
-       pci_free_consistent(pdev, sizeof(u32), instance->consumer,
-                           instance->consumer_h);
+       free_irq(instance->msi_flag ? instance->msixentry.vector :
+                instance->pdev->irq, instance);
+       if (instance->msi_flag)
+               pci_disable_msix(instance->pdev);
+
+       switch (instance->pdev->device) {
+       case PCI_DEVICE_ID_LSI_FUSION:
+               megasas_release_fusion(instance);
+               for (i = 0; i < 2 ; i++)
+                       if (fusion->ld_map[i])
+                               dma_free_coherent(&instance->pdev->dev,
+                                                 fusion->map_sz,
+                                                 fusion->ld_map[i],
+                                                 fusion->
+                                                 ld_map_phys[i]);
+               kfree(instance->ctrl_context);
+               break;
+       default:
+               megasas_release_mfi(instance);
+               pci_free_consistent(pdev,
+                                   sizeof(struct megasas_evt_detail),
+                                   instance->evt_detail,
+                                   instance->evt_detail_h);
+               pci_free_consistent(pdev, sizeof(u32),
+                                   instance->producer,
+                                   instance->producer_h);
+               pci_free_consistent(pdev, sizeof(u32),
+                                   instance->consumer,
+                                   instance->consumer_h);
+               break;
+       }
 
        scsi_host_put(host);
 
@@ -4984,6 +5236,7 @@ megasas_aen_polling(struct work_struct *work)
                        break;
                case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
                case MR_EVT_FOREIGN_CFG_IMPORTED:
+               case MR_EVT_LD_STATE_CHANGE:
                        doscan = 1;
                        break;
                default:
@@ -5163,7 +5416,7 @@ err_dcf_attr_ver:
        pci_unregister_driver(&megasas_pci_driver);
 err_pcidrv:
        unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
-       return rval;
+       return rval;
 }
 
 /**
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
new file mode 100644 (file)
index 0000000..53fa96a
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ *  Linux MegaRAID driver for SAS based RAID controllers
+ *
+ *  Copyright (c) 2009-2011  LSI Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *  FILE: megaraid_sas_fp.c
+ *
+ *  Authors: LSI Corporation
+ *           Sumant Patro
+ *           Varad Talamacki
+ *           Manoj Jose
+ *
+ *  Send feedback to: <megaraidlinux@lsi.com>
+ *
+ *  Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ *     ATTN: Linuxraid
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/smp_lock.h>
+#include <linux/uio.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/compat.h>
+#include <linux/blkdev.h>
+#include <linux/poll.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
+#include "megaraid_sas_fusion.h"
+#include <asm/div64.h>
+
+#define ABS_DIFF(a, b)   (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
+#define MR_LD_STATE_OPTIMAL 3
+#define FALSE 0
+#define TRUE 1
+
+/* Prototypes */
+void
+mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
+                             struct LD_LOAD_BALANCE_INFO *lbInfo);
+
+u32 mega_mod64(u64 dividend, u32 divisor)
+{
+       u64 d;
+       u32 remainder;
+
+       if (!divisor)
+               printk(KERN_ERR "megasas : DIVISOR is zero, in div fn\n");
+       d = dividend;
+       remainder = do_div(d, divisor);
+       return remainder;
+}
+
+/**
+ * @param dividend    : Dividend
+ * @param divisor    : Divisor
+ *
+ * @return quotient
+ **/
+u64 mega_div64_32(uint64_t dividend, uint32_t divisor)
+{
+       u32 remainder;
+       u64 d;
+
+       if (!divisor)
+               printk(KERN_ERR "megasas : DIVISOR is zero in mod fn\n");
+
+       d = dividend;
+       remainder = do_div(d, divisor);
+
+       return d;
+}
+
+struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map)
+{
+       return &map->raidMap.ldSpanMap[ld].ldRaid;
+}
+
+static struct MR_SPAN_BLOCK_INFO *MR_LdSpanInfoGet(u32 ld,
+                                                  struct MR_FW_RAID_MAP_ALL
+                                                  *map)
+{
+       return &map->raidMap.ldSpanMap[ld].spanBlock[0];
+}
+
+static u8 MR_LdDataArmGet(u32 ld, u32 armIdx, struct MR_FW_RAID_MAP_ALL *map)
+{
+       return map->raidMap.ldSpanMap[ld].dataArmMap[armIdx];
+}
+
+static u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_FW_RAID_MAP_ALL *map)
+{
+       return map->raidMap.arMapInfo[ar].pd[arm];
+}
+
+static u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_FW_RAID_MAP_ALL *map)
+{
+       return map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef;
+}
+
+static u16 MR_PdDevHandleGet(u32 pd, struct MR_FW_RAID_MAP_ALL *map)
+{
+       return map->raidMap.devHndlInfo[pd].curDevHdl;
+}
+
+u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map)
+{
+       return map->raidMap.ldSpanMap[ld].ldRaid.targetId;
+}
+
+u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map)
+{
+       return map->raidMap.ldTgtIdToLd[ldTgtId];
+}
+
+static struct MR_LD_SPAN *MR_LdSpanPtrGet(u32 ld, u32 span,
+                                         struct MR_FW_RAID_MAP_ALL *map)
+{
+       return &map->raidMap.ldSpanMap[ld].spanBlock[span].span;
+}
+
+/*
+ * This function will validate Map info data provided by FW
+ */
+u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
+                     struct LD_LOAD_BALANCE_INFO *lbInfo)
+{
+       struct MR_FW_RAID_MAP *pFwRaidMap = &map->raidMap;
+
+       if (pFwRaidMap->totalSize !=
+           (sizeof(struct MR_FW_RAID_MAP) -sizeof(struct MR_LD_SPAN_MAP) +
+            (sizeof(struct MR_LD_SPAN_MAP) *pFwRaidMap->ldCount))) {
+               printk(KERN_ERR "megasas: map info structure size 0x%x is not matching with ld count\n",
+                      (unsigned int)((sizeof(struct MR_FW_RAID_MAP) -
+                                      sizeof(struct MR_LD_SPAN_MAP)) +
+                                     (sizeof(struct MR_LD_SPAN_MAP) *
+                                      pFwRaidMap->ldCount)));
+               printk(KERN_ERR "megasas: span map %x, pFwRaidMap->totalSize "
+                      ": %x\n", (unsigned int)sizeof(struct MR_LD_SPAN_MAP),
+                      pFwRaidMap->totalSize);
+               return 0;
+       }
+
+       mr_update_load_balance_params(map, lbInfo);
+
+       return 1;
+}
+
+u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
+                   struct MR_FW_RAID_MAP_ALL *map, int *div_error)
+{
+       struct MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map);
+       struct MR_QUAD_ELEMENT    *quad;
+       struct MR_LD_RAID         *raid = MR_LdRaidGet(ld, map);
+       u32                span, j;
+
+       for (span = 0; span < raid->spanDepth; span++, pSpanBlock++) {
+
+               for (j = 0; j < pSpanBlock->block_span_info.noElements; j++) {
+                       quad = &pSpanBlock->block_span_info.quad[j];
+
+                       if (quad->diff == 0) {
+                               *div_error = 1;
+                               return span;
+                       }
+                       if (quad->logStart <= row  &&  row <= quad->logEnd  &&
+                           (mega_mod64(row-quad->logStart, quad->diff)) == 0) {
+                               if (span_blk != NULL) {
+                                       u64  blk, debugBlk;
+                                       blk =
+                                               mega_div64_32(
+                                                       (row-quad->logStart),
+                                                       quad->diff);
+                                       debugBlk = blk;
+
+                                       blk = (blk + quad->offsetInSpan) <<
+                                               raid->stripeShift;
+                                       *span_blk = blk;
+                               }
+                               return span;
+                       }
+               }
+       }
+       return span;
+}
+
+/*
+******************************************************************************
+*
+* This routine calculates the arm, span and block for the specified stripe and
+* reference in stripe.
+*
+* Inputs :
+*
+*    ld   - Logical drive number
+*    stripRow        - Stripe number
+*    stripRef    - Reference in stripe
+*
+* Outputs :
+*
+*    span          - Span number
+*    block         - Absolute Block number in the physical disk
+*/
+u8 MR_GetPhyParams(u32 ld, u64 stripRow, u16 stripRef, u64 *pdBlock,
+                  u16 *pDevHandle, struct RAID_CONTEXT *pRAID_Context,
+                  struct MR_FW_RAID_MAP_ALL *map)
+{
+       struct MR_LD_RAID  *raid = MR_LdRaidGet(ld, map);
+       u32         pd, arRef;
+       u8          physArm, span;
+       u64         row;
+       u8          retval = TRUE;
+       int         error_code = 0;
+
+       row =  mega_div64_32(stripRow, raid->rowDataSize);
+
+       if (raid->level == 6) {
+               /* logical arm within row */
+               u32 logArm =  mega_mod64(stripRow, raid->rowDataSize);
+               u32 rowMod, armQ, arm;
+
+               if (raid->rowSize == 0)
+                       return FALSE;
+               /* get logical row mod */
+               rowMod = mega_mod64(row, raid->rowSize);
+               armQ = raid->rowSize-1-rowMod; /* index of Q drive */
+               arm = armQ+1+logArm; /* data always logically follows Q */
+               if (arm >= raid->rowSize) /* handle wrap condition */
+                       arm -= raid->rowSize;
+               physArm = (u8)arm;
+       } else  {
+               if (raid->modFactor == 0)
+                       return FALSE;
+               physArm = MR_LdDataArmGet(ld,  mega_mod64(stripRow,
+                                                         raid->modFactor),
+                                         map);
+       }
+
+       if (raid->spanDepth == 1) {
+               span = 0;
+               *pdBlock = row << raid->stripeShift;
+       } else {
+               span = (u8)MR_GetSpanBlock(ld, row, pdBlock, map, &error_code);
+               if (error_code == 1)
+                       return FALSE;
+       }
+
+       /* Get the array on which this span is present */
+       arRef       = MR_LdSpanArrayGet(ld, span, map);
+       pd          = MR_ArPdGet(arRef, physArm, map); /* Get the pd */
+
+       if (pd != MR_PD_INVALID)
+               /* Get dev handle from Pd. */
+               *pDevHandle = MR_PdDevHandleGet(pd, map);
+       else {
+               *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
+               if (raid->level >= 5)
+                       pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
+               else if (raid->level == 1) {
+                       /* Get alternate Pd. */
+                       pd = MR_ArPdGet(arRef, physArm + 1, map);
+                       if (pd != MR_PD_INVALID)
+                               /* Get dev handle from Pd */
+                               *pDevHandle = MR_PdDevHandleGet(pd, map);
+               }
+               retval = FALSE;
+       }
+
+       *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
+       pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
+               physArm;
+       return retval;
+}
+
+/*
+******************************************************************************
+*
+* MR_BuildRaidContext function
+*
+* This function will initiate command processing.  The start/end row and strip
+* information is calculated then the lock is acquired.
+* This function will return 0 if region lock was acquired OR return num strips
+*/
+u8
+MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info,
+                   struct RAID_CONTEXT *pRAID_Context,
+                   struct MR_FW_RAID_MAP_ALL *map)
+{
+       struct MR_LD_RAID  *raid;
+       u32         ld, stripSize, stripe_mask;
+       u64         endLba, endStrip, endRow, start_row, start_strip;
+       u64         regStart;
+       u32         regSize;
+       u8          num_strips, numRows;
+       u16         ref_in_start_stripe, ref_in_end_stripe;
+       u64         ldStartBlock;
+       u32         numBlocks, ldTgtId;
+       u8          isRead;
+       u8          retval = 0;
+
+       ldStartBlock = io_info->ldStartBlock;
+       numBlocks = io_info->numBlocks;
+       ldTgtId = io_info->ldTgtId;
+       isRead = io_info->isRead;
+
+       ld = MR_TargetIdToLdGet(ldTgtId, map);
+       raid = MR_LdRaidGet(ld, map);
+
+       stripSize = 1 << raid->stripeShift;
+       stripe_mask = stripSize-1;
+       /*
+        * calculate starting row and stripe, and number of strips and rows
+        */
+       start_strip         = ldStartBlock >> raid->stripeShift;
+       ref_in_start_stripe = (u16)(ldStartBlock & stripe_mask);
+       endLba              = ldStartBlock + numBlocks - 1;
+       ref_in_end_stripe   = (u16)(endLba & stripe_mask);
+       endStrip            = endLba >> raid->stripeShift;
+       num_strips          = (u8)(endStrip - start_strip + 1); /* End strip */
+       if (raid->rowDataSize == 0)
+               return FALSE;
+       start_row           =  mega_div64_32(start_strip, raid->rowDataSize);
+       endRow              =  mega_div64_32(endStrip, raid->rowDataSize);
+       numRows             = (u8)(endRow - start_row + 1);
+
+       /*
+        * calculate region info.
+        */
+
+       /* assume region is at the start of the first row */
+       regStart            = start_row << raid->stripeShift;
+       /* assume this IO needs the full row - we'll adjust if not true */
+       regSize             = stripSize;
+
+       /* If IO spans more than 1 strip, fp is not possible
+          FP is not possible for writes on non-0 raid levels
+          FP is not possible if LD is not capable */
+       if (num_strips > 1 || (!isRead && raid->level != 0) ||
+           !raid->capability.fpCapable) {
+               io_info->fpOkForIo = FALSE;
+       } else {
+               io_info->fpOkForIo = TRUE;
+       }
+
+       if (numRows == 1) {
+               /* single-strip IOs can always lock only the data needed */
+               if (num_strips == 1) {
+                       regStart += ref_in_start_stripe;
+                       regSize = numBlocks;
+               }
+               /* multi-strip IOs always need to full stripe locked */
+       } else {
+               if (start_strip == (start_row + 1) * raid->rowDataSize - 1) {
+                       /* If the start strip is the last in the start row */
+                       regStart += ref_in_start_stripe;
+                       regSize = stripSize - ref_in_start_stripe;
+                       /* initialize count to sectors from startref to end
+                          of strip */
+               }
+
+               if (numRows > 2)
+                       /* Add complete rows in the middle of the transfer */
+                       regSize += (numRows-2) << raid->stripeShift;
+
+               /* if IO ends within first strip of last row */
+               if (endStrip == endRow*raid->rowDataSize)
+                       regSize += ref_in_end_stripe+1;
+               else
+                       regSize += stripSize;
+       }
+
+       pRAID_Context->timeoutValue     = map->raidMap.fpPdIoTimeoutSec;
+       pRAID_Context->regLockFlags     = (isRead) ? REGION_TYPE_SHARED_READ :
+               raid->regTypeReqOnWrite;
+       pRAID_Context->VirtualDiskTgtId = raid->targetId;
+       pRAID_Context->regLockRowLBA    = regStart;
+       pRAID_Context->regLockLength    = regSize;
+       pRAID_Context->configSeqNum     = raid->seqNum;
+
+       /*Get Phy Params only if FP capable, or else leave it to MR firmware
+         to do the calculation.*/
+       if (io_info->fpOkForIo) {
+               retval = MR_GetPhyParams(ld, start_strip, ref_in_start_stripe,
+                                        &io_info->pdBlock,
+                                        &io_info->devHandle, pRAID_Context,
+                                        map);
+               /* If IO on an invalid Pd, then FP i snot possible */
+               if (io_info->devHandle == MR_PD_INVALID)
+                       io_info->fpOkForIo = FALSE;
+               return retval;
+       } else if (isRead) {
+               uint stripIdx;
+               for (stripIdx = 0; stripIdx < num_strips; stripIdx++) {
+                       if (!MR_GetPhyParams(ld, start_strip + stripIdx,
+                                            ref_in_start_stripe,
+                                            &io_info->pdBlock,
+                                            &io_info->devHandle,
+                                            pRAID_Context, map))
+                               return TRUE;
+               }
+       }
+       return TRUE;
+}
+
+void
+mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
+                             struct LD_LOAD_BALANCE_INFO *lbInfo)
+{
+       int ldCount;
+       u16 ld;
+       struct MR_LD_RAID *raid;
+
+       for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
+               ld = MR_TargetIdToLdGet(ldCount, map);
+               if (ld >= MAX_LOGICAL_DRIVES) {
+                       lbInfo[ldCount].loadBalanceFlag = 0;
+                       continue;
+               }
+
+               raid = MR_LdRaidGet(ld, map);
+
+               /* Two drive Optimal RAID 1 */
+               if ((raid->level == 1)  &&  (raid->rowSize == 2) &&
+                   (raid->spanDepth == 1) && raid->ldState ==
+                   MR_LD_STATE_OPTIMAL) {
+                       u32 pd, arRef;
+
+                       lbInfo[ldCount].loadBalanceFlag = 1;
+
+                       /* Get the array on which this span is present */
+                       arRef = MR_LdSpanArrayGet(ld, 0, map);
+
+                       /* Get the Pd */
+                       pd = MR_ArPdGet(arRef, 0, map);
+                       /* Get dev handle from Pd */
+                       lbInfo[ldCount].raid1DevHandle[0] =
+                               MR_PdDevHandleGet(pd, map);
+                       /* Get the Pd */
+                       pd = MR_ArPdGet(arRef, 1, map);
+
+                       /* Get the dev handle from Pd */
+                       lbInfo[ldCount].raid1DevHandle[1] =
+                               MR_PdDevHandleGet(pd, map);
+               } else
+                       lbInfo[ldCount].loadBalanceFlag = 0;
+       }
+}
+
+u8 megasas_get_best_arm(struct LD_LOAD_BALANCE_INFO *lbInfo, u8 arm, u64 block,
+                       u32 count)
+{
+       u16     pend0, pend1;
+       u64     diff0, diff1;
+       u8      bestArm;
+
+       /* get the pending cmds for the data and mirror arms */
+       pend0 = atomic_read(&lbInfo->scsi_pending_cmds[0]);
+       pend1 = atomic_read(&lbInfo->scsi_pending_cmds[1]);
+
+       /* Determine the disk whose head is nearer to the req. block */
+       diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[0]);
+       diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]);
+       bestArm = (diff0 <= diff1 ? 0 : 1);
+
+       if ((bestArm == arm && pend0 > pend1 + 16)  ||
+           (bestArm != arm && pend1 > pend0 + 16))
+               bestArm ^= 1;
+
+       /* Update the last accessed block on the correct pd */
+       lbInfo->last_accessed_block[bestArm] = block + count - 1;
+
+       return bestArm;
+}
+
+u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo,
+                          struct IO_REQUEST_INFO *io_info)
+{
+       u8 arm, old_arm;
+       u16 devHandle;
+
+       old_arm = lbInfo->raid1DevHandle[0] == io_info->devHandle ? 0 : 1;
+
+       /* get best new arm */
+       arm  = megasas_get_best_arm(lbInfo, old_arm, io_info->ldStartBlock,
+                                   io_info->numBlocks);
+       devHandle = lbInfo->raid1DevHandle[arm];
+       atomic_inc(&lbInfo->scsi_pending_cmds[arm]);
+
+       return devHandle;
+}
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
new file mode 100644 (file)
index 0000000..c1e09d5
--- /dev/null
@@ -0,0 +1,2248 @@
+/*
+ *  Linux MegaRAID driver for SAS based RAID controllers
+ *
+ *  Copyright (c) 2009-2011  LSI Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *  FILE: megaraid_sas_fusion.c
+ *
+ *  Authors: LSI Corporation
+ *           Sumant Patro
+ *           Adam Radford <linuxraid@lsi.com>
+ *
+ *  Send feedback to: <megaraidlinux@lsi.com>
+ *
+ *  Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ *     ATTN: Linuxraid
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/smp_lock.h>
+#include <linux/uio.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/compat.h>
+#include <linux/blkdev.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
+#include "megaraid_sas_fusion.h"
+#include "megaraid_sas.h"
+
+extern void megasas_free_cmds(struct megasas_instance *instance);
+extern struct megasas_cmd *megasas_get_cmd(struct megasas_instance
+                                          *instance);
+extern void
+megasas_complete_cmd(struct megasas_instance *instance,
+                    struct megasas_cmd *cmd, u8 alt_status);
+int megasas_is_ldio(struct scsi_cmnd *cmd);
+int
+wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd);
+
+void
+megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd);
+int megasas_alloc_cmds(struct megasas_instance *instance);
+int
+megasas_clear_intr_fusion(struct megasas_register_set __iomem *regs);
+int
+megasas_issue_polled(struct megasas_instance *instance,
+                    struct megasas_cmd *cmd);
+
+u8
+MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info,
+                   struct RAID_CONTEXT *pRAID_Context,
+                   struct MR_FW_RAID_MAP_ALL *map);
+u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map);
+struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map);
+
+u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map);
+u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
+                     struct LD_LOAD_BALANCE_INFO *lbInfo);
+u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo,
+                          struct IO_REQUEST_INFO *in_info);
+int megasas_transition_to_ready(struct megasas_instance *instance);
+void megaraid_sas_kill_hba(struct megasas_instance *instance);
+
+extern u32 megasas_dbg_lvl;
+
+/**
+ * megasas_enable_intr_fusion -        Enables interrupts
+ * @regs:                      MFI register set
+ */
+void
+megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs)
+{
+       writel(~MFI_FUSION_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr_fusion - Disables interrupt
+ * @regs:                       MFI register set
+ */
+void
+megasas_disable_intr_fusion(struct megasas_register_set __iomem *regs)
+{
+       u32 mask = 0xFFFFFFFF;
+       u32 status;
+
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       status = readl(&regs->outbound_intr_mask);
+}
+
+int
+megasas_clear_intr_fusion(struct megasas_register_set __iomem *regs)
+{
+       u32 status;
+       /*
+        * Check if it is our interrupt
+        */
+       status = readl(&regs->outbound_intr_status);
+
+       if (status & 1) {
+               writel(status, &regs->outbound_intr_status);
+               readl(&regs->outbound_intr_status);
+               return 1;
+       }
+       if (!(status & MFI_FUSION_ENABLE_INTERRUPT_MASK))
+               return 0;
+
+       /*
+        * dummy read to flush PCI
+        */
+       readl(&regs->outbound_intr_status);
+
+       return 1;
+}
+
+/**
+ * megasas_get_cmd_fusion -    Get a command from the free pool
+ * @instance:          Adapter soft state
+ *
+ * Returns a free command from the pool
+ */
+struct megasas_cmd_fusion *megasas_get_cmd_fusion(struct megasas_instance
+                                                 *instance)
+{
+       unsigned long flags;
+       struct fusion_context *fusion =
+               (struct fusion_context *)instance->ctrl_context;
+       struct megasas_cmd_fusion *cmd = NULL;
+
+       spin_lock_irqsave(&fusion->cmd_pool_lock, flags);
+
+       if (!list_empty(&fusion->cmd_pool)) {
+               cmd = list_entry((&fusion->cmd_pool)->next,
+                                struct megasas_cmd_fusion, list);
+               list_del_init(&cmd->list);
+       } else {
+               printk(KERN_ERR "megasas: Command pool (fusion) empty!\n");
+       }
+
+       spin_unlock_irqrestore(&fusion->cmd_pool_lock, flags);
+       return cmd;
+}
+
+/**
+ * megasas_return_cmd_fusion - Return a cmd to free command pool
+ * @instance:          Adapter soft state
+ * @cmd:               Command packet to be returned to free command pool
+ */
+static inline void
+megasas_return_cmd_fusion(struct megasas_instance *instance,
+                         struct megasas_cmd_fusion *cmd)
+{
+       unsigned long flags;
+       struct fusion_context *fusion =
+               (struct fusion_context *)instance->ctrl_context;
+
+       spin_lock_irqsave(&fusion->cmd_pool_lock, flags);
+
+       cmd->scmd = NULL;
+       cmd->sync_cmd_idx = (u32)ULONG_MAX;
+       list_add_tail(&cmd->list, &fusion->cmd_pool);
+
+       spin_unlock_irqrestore(&fusion->cmd_pool_lock, flags);
+}
+
+/**
+ * megasas_teardown_frame_pool_fusion -        Destroy the cmd frame DMA pool
+ * @instance:                          Adapter soft state
+ */
+static void megasas_teardown_frame_pool_fusion(
+       struct megasas_instance *instance)
+{
+       int i;
+       struct fusion_context *fusion = instance->ctrl_context;
+
+       u16 max_cmd = instance->max_fw_cmds;
+
+       struct megasas_cmd_fusion *cmd;
+
+       if (!fusion->sg_dma_pool || !fusion->sense_dma_pool) {
+               printk(KERN_ERR "megasas: dma pool is null. SG Pool %p, "
+                      "sense pool : %p\n", fusion->sg_dma_pool,
+                      fusion->sense_dma_pool);
+               return;
+       }
+
+       /*
+        * Return all frames to pool
+        */
+       for (i = 0; i < max_cmd; i++) {
+
+               cmd = fusion->cmd_list[i];
+
+               if (cmd->sg_frame)
+                       pci_pool_free(fusion->sg_dma_pool, cmd->sg_frame,
+                                     cmd->sg_frame_phys_addr);
+
+               if (cmd->sense)
+                       pci_pool_free(fusion->sense_dma_pool, cmd->sense,
+                                     cmd->sense_phys_addr);
+       }
+
+       /*
+        * Now destroy the pool itself
+        */
+       pci_pool_destroy(fusion->sg_dma_pool);
+       pci_pool_destroy(fusion->sense_dma_pool);
+
+       fusion->sg_dma_pool = NULL;
+       fusion->sense_dma_pool = NULL;
+}
+
+/**
+ * megasas_free_cmds_fusion -  Free all the cmds in the free cmd pool
+ * @instance:          Adapter soft state
+ */
+void
+megasas_free_cmds_fusion(struct megasas_instance *instance)
+{
+       int i;
+       struct fusion_context *fusion = instance->ctrl_context;
+
+       u32 max_cmds, req_sz, reply_sz, io_frames_sz;
+
+
+       req_sz = fusion->request_alloc_sz;
+       reply_sz = fusion->reply_alloc_sz;
+       io_frames_sz = fusion->io_frames_alloc_sz;
+
+       max_cmds = instance->max_fw_cmds;
+
+       /* Free descriptors and request Frames memory */
+       if (fusion->req_frames_desc)
+               dma_free_coherent(&instance->pdev->dev, req_sz,
+                                 fusion->req_frames_desc,
+                                 fusion->req_frames_desc_phys);
+
+       if (fusion->reply_frames_desc) {
+               pci_pool_free(fusion->reply_frames_desc_pool,
+                             fusion->reply_frames_desc,
+                             fusion->reply_frames_desc_phys);
+               pci_pool_destroy(fusion->reply_frames_desc_pool);
+       }
+
+       if (fusion->io_request_frames) {
+               pci_pool_free(fusion->io_request_frames_pool,
+                             fusion->io_request_frames,
+                             fusion->io_request_frames_phys);
+               pci_pool_destroy(fusion->io_request_frames_pool);
+       }
+
+       /* Free the Fusion frame pool */
+       megasas_teardown_frame_pool_fusion(instance);
+
+       /* Free all the commands in the cmd_list */
+       for (i = 0; i < max_cmds; i++)
+               kfree(fusion->cmd_list[i]);
+
+       /* Free the cmd_list buffer itself */
+       kfree(fusion->cmd_list);
+       fusion->cmd_list = NULL;
+
+       INIT_LIST_HEAD(&fusion->cmd_pool);
+}
+
+/**
+ * megasas_create_frame_pool_fusion -  Creates DMA pool for cmd frames
+ * @instance:                  Adapter soft state
+ *
+ */
+static int megasas_create_frame_pool_fusion(struct megasas_instance *instance)
+{
+       int i;
+       u32 max_cmd;
+       struct fusion_context *fusion;
+       struct megasas_cmd_fusion *cmd;
+       u32 total_sz_chain_frame;
+
+       fusion = instance->ctrl_context;
+       max_cmd = instance->max_fw_cmds;
+
+       total_sz_chain_frame = MEGASAS_MAX_SZ_CHAIN_FRAME;
+
+       /*
+        * Use DMA pool facility provided by PCI layer
+        */
+
+       fusion->sg_dma_pool = pci_pool_create("megasas sg pool fusion",
+                                             instance->pdev,
+                                             total_sz_chain_frame, 4,
+                                             0);
+       if (!fusion->sg_dma_pool) {
+               printk(KERN_DEBUG "megasas: failed to setup request pool "
+                      "fusion\n");
+               return -ENOMEM;
+       }
+       fusion->sense_dma_pool = pci_pool_create("megasas sense pool fusion",
+                                                instance->pdev,
+                                                SCSI_SENSE_BUFFERSIZE, 64, 0);
+
+       if (!fusion->sense_dma_pool) {
+               printk(KERN_DEBUG "megasas: failed to setup sense pool "
+                      "fusion\n");
+               pci_pool_destroy(fusion->sg_dma_pool);
+               fusion->sg_dma_pool = NULL;
+               return -ENOMEM;
+       }
+
+       /*
+        * Allocate and attach a frame to each of the commands in cmd_list
+        */
+       for (i = 0; i < max_cmd; i++) {
+
+               cmd = fusion->cmd_list[i];
+
+               cmd->sg_frame = pci_pool_alloc(fusion->sg_dma_pool,
+                                              GFP_KERNEL,
+                                              &cmd->sg_frame_phys_addr);
+
+               cmd->sense = pci_pool_alloc(fusion->sense_dma_pool,
+                                           GFP_KERNEL, &cmd->sense_phys_addr);
+               /*
+                * megasas_teardown_frame_pool_fusion() takes care of freeing
+                * whatever has been allocated
+                */
+               if (!cmd->sg_frame || !cmd->sense) {
+                       printk(KERN_DEBUG "megasas: pci_pool_alloc failed\n");
+                       megasas_teardown_frame_pool_fusion(instance);
+                       return -ENOMEM;
+               }
+       }
+       return 0;
+}
+
+/**
+ * megasas_alloc_cmds_fusion - Allocates the command packets
+ * @instance:          Adapter soft state
+ *
+ *
+ * Each frame has a 32-bit field called context. This context is used to get
+ * back the megasas_cmd_fusion from the frame when a frame gets completed
+ * In this driver, the 32 bit values are the indices into an array cmd_list.
+ * This array is used only to look up the megasas_cmd_fusion given the context.
+ * The free commands themselves are maintained in a linked list called cmd_pool.
+ *
+ * cmds are formed in the io_request and sg_frame members of the
+ * megasas_cmd_fusion. The context field is used to get a request descriptor
+ * and is used as SMID of the cmd.
+ * SMID value range is from 1 to max_fw_cmds.
+ */
+int
+megasas_alloc_cmds_fusion(struct megasas_instance *instance)
+{
+       int i, j;
+       u32 max_cmd, io_frames_sz;
+       struct fusion_context *fusion;
+       struct megasas_cmd_fusion *cmd;
+       union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
+       u32 offset;
+       dma_addr_t io_req_base_phys;
+       u8 *io_req_base;
+
+       fusion = instance->ctrl_context;
+
+       max_cmd = instance->max_fw_cmds;
+
+       fusion->req_frames_desc =
+               dma_alloc_coherent(&instance->pdev->dev,
+                                  fusion->request_alloc_sz,
+                                  &fusion->req_frames_desc_phys, GFP_KERNEL);
+
+       if (!fusion->req_frames_desc) {
+               printk(KERN_ERR "megasas; Could not allocate memory for "
+                      "request_frames\n");
+               goto fail_req_desc;
+       }
+
+       fusion->reply_frames_desc_pool =
+               pci_pool_create("reply_frames pool", instance->pdev,
+                               fusion->reply_alloc_sz, 16, 0);
+
+       if (!fusion->reply_frames_desc_pool) {
+               printk(KERN_ERR "megasas; Could not allocate memory for "
+                      "reply_frame pool\n");
+               goto fail_reply_desc;
+       }
+
+       fusion->reply_frames_desc =
+               pci_pool_alloc(fusion->reply_frames_desc_pool, GFP_KERNEL,
+                              &fusion->reply_frames_desc_phys);
+       if (!fusion->reply_frames_desc) {
+               printk(KERN_ERR "megasas; Could not allocate memory for "
+                      "reply_frame pool\n");
+               pci_pool_destroy(fusion->reply_frames_desc_pool);
+               goto fail_reply_desc;
+       }
+
+       reply_desc = fusion->reply_frames_desc;
+       for (i = 0; i < fusion->reply_q_depth; i++, reply_desc++)
+               reply_desc->Words = ULLONG_MAX;
+
+       io_frames_sz = fusion->io_frames_alloc_sz;
+
+       fusion->io_request_frames_pool =
+               pci_pool_create("io_request_frames pool", instance->pdev,
+                               fusion->io_frames_alloc_sz, 16, 0);
+
+       if (!fusion->io_request_frames_pool) {
+               printk(KERN_ERR "megasas: Could not allocate memory for "
+                      "io_request_frame pool\n");
+               goto fail_io_frames;
+       }
+
+       fusion->io_request_frames =
+               pci_pool_alloc(fusion->io_request_frames_pool, GFP_KERNEL,
+                              &fusion->io_request_frames_phys);
+       if (!fusion->io_request_frames) {
+               printk(KERN_ERR "megasas: Could not allocate memory for "
+                      "io_request_frames frames\n");
+               pci_pool_destroy(fusion->io_request_frames_pool);
+               goto fail_io_frames;
+       }
+
+       /*
+        * fusion->cmd_list is an array of struct megasas_cmd_fusion pointers.
+        * Allocate the dynamic array first and then allocate individual
+        * commands.
+        */
+       fusion->cmd_list = kmalloc(sizeof(struct megasas_cmd_fusion *)
+                                  *max_cmd, GFP_KERNEL);
+
+       if (!fusion->cmd_list) {
+               printk(KERN_DEBUG "megasas: out of memory. Could not alloc "
+                      "memory for cmd_list_fusion\n");
+               goto fail_cmd_list;
+       }
+
+       memset(fusion->cmd_list, 0, sizeof(struct megasas_cmd_fusion *)
+              *max_cmd);
+
+       max_cmd = instance->max_fw_cmds;
+       for (i = 0; i < max_cmd; i++) {
+               fusion->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd_fusion),
+                                             GFP_KERNEL);
+               if (!fusion->cmd_list[i]) {
+                       printk(KERN_ERR "Could not alloc cmd list fusion\n");
+
+                       for (j = 0; j < i; j++)
+                               kfree(fusion->cmd_list[j]);
+
+                       kfree(fusion->cmd_list);
+                       fusion->cmd_list = NULL;
+                       goto fail_cmd_list;
+               }
+       }
+
+       /* The first 256 bytes (SMID 0) is not used. Don't add to cmd list */
+       io_req_base = fusion->io_request_frames +
+               MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
+       io_req_base_phys = fusion->io_request_frames_phys +
+               MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
+
+       /*
+        * Add all the commands to command pool (fusion->cmd_pool)
+        */
+
+       /* SMID 0 is reserved. Set SMID/index from 1 */
+       for (i = 0; i < max_cmd; i++) {
+               cmd = fusion->cmd_list[i];
+               offset = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * i;
+               memset(cmd, 0, sizeof(struct megasas_cmd_fusion));
+               cmd->index = i + 1;
+               cmd->scmd = NULL;
+               cmd->sync_cmd_idx = (u32)ULONG_MAX; /* Set to Invalid */
+               cmd->instance = instance;
+               cmd->io_request =
+                       (struct MPI2_RAID_SCSI_IO_REQUEST *)
+                 (io_req_base + offset);
+               memset(cmd->io_request, 0,
+                      sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
+               cmd->io_request_phys_addr = io_req_base_phys + offset;
+
+               list_add_tail(&cmd->list, &fusion->cmd_pool);
+       }
+
+       /*
+        * Create a frame pool and assign one frame to each cmd
+        */
+       if (megasas_create_frame_pool_fusion(instance)) {
+               printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
+               megasas_free_cmds_fusion(instance);
+               goto fail_req_desc;
+       }
+
+       return 0;
+
+fail_cmd_list:
+       pci_pool_free(fusion->io_request_frames_pool, fusion->io_request_frames,
+                     fusion->io_request_frames_phys);
+       pci_pool_destroy(fusion->io_request_frames_pool);
+fail_io_frames:
+       dma_free_coherent(&instance->pdev->dev, fusion->request_alloc_sz,
+                         fusion->reply_frames_desc,
+                         fusion->reply_frames_desc_phys);
+       pci_pool_free(fusion->reply_frames_desc_pool,
+                     fusion->reply_frames_desc,
+                     fusion->reply_frames_desc_phys);
+       pci_pool_destroy(fusion->reply_frames_desc_pool);
+
+fail_reply_desc:
+       dma_free_coherent(&instance->pdev->dev, fusion->request_alloc_sz,
+                         fusion->req_frames_desc,
+                         fusion->req_frames_desc_phys);
+fail_req_desc:
+       return -ENOMEM;
+}
+
+/**
+ * wait_and_poll -     Issues a polling command
+ * @instance:                  Adapter soft state
+ * @cmd:                       Command packet to be issued
+ *
+ * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
+ */
+int
+wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+       int i;
+       struct megasas_header *frame_hdr = &cmd->frame->hdr;
+
+       u32 msecs = MFI_POLL_TIMEOUT_SECS * 1000;
+
+       /*
+        * Wait for cmd_status to change
+        */
+       for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i += 20) {
+               rmb();
+               msleep(20);
+       }
+
+       if (frame_hdr->cmd_status == 0xff)
+               return -ETIME;
+
+       return 0;
+}
+
+/**
+ * megasas_ioc_init_fusion -   Initializes the FW
+ * @instance:          Adapter soft state
+ *
+ * Issues the IOC Init cmd
+ */
+int
+megasas_ioc_init_fusion(struct megasas_instance *instance)
+{
+       struct megasas_init_frame *init_frame;
+       struct MPI2_IOC_INIT_REQUEST *IOCInitMessage;
+       dma_addr_t      ioc_init_handle;
+       u32 context;
+       struct megasas_cmd *cmd;
+       u8 ret;
+       struct fusion_context *fusion;
+       union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+       int i;
+       struct megasas_header *frame_hdr;
+
+       fusion = instance->ctrl_context;
+
+       cmd = megasas_get_cmd(instance);
+
+       if (!cmd) {
+               printk(KERN_ERR "Could not allocate cmd for INIT Frame\n");
+               ret = 1;
+               goto fail_get_cmd;
+       }
+
+       IOCInitMessage =
+         dma_alloc_coherent(&instance->pdev->dev,
+                            sizeof(struct MPI2_IOC_INIT_REQUEST),
+                            &ioc_init_handle, GFP_KERNEL);
+
+       if (!IOCInitMessage) {
+               printk(KERN_ERR "Could not allocate memory for "
+                      "IOCInitMessage\n");
+               ret = 1;
+               goto fail_fw_init;
+       }
+
+       memset(IOCInitMessage, 0, sizeof(struct MPI2_IOC_INIT_REQUEST));
+
+       IOCInitMessage->Function = MPI2_FUNCTION_IOC_INIT;
+       IOCInitMessage->WhoInit = MPI2_WHOINIT_HOST_DRIVER;
+       IOCInitMessage->MsgVersion = MPI2_VERSION;
+       IOCInitMessage->HeaderVersion = MPI2_HEADER_VERSION;
+       IOCInitMessage->SystemRequestFrameSize =
+               MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE / 4;
+
+       IOCInitMessage->ReplyDescriptorPostQueueDepth = fusion->reply_q_depth;
+       IOCInitMessage->ReplyDescriptorPostQueueAddress =
+               fusion->reply_frames_desc_phys;
+       IOCInitMessage->SystemRequestFrameBaseAddress =
+               fusion->io_request_frames_phys;
+
+       init_frame = (struct megasas_init_frame *)cmd->frame;
+       memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
+
+       frame_hdr = &cmd->frame->hdr;
+       context = init_frame->context;
+       init_frame->context = context;
+
+       frame_hdr->cmd_status = 0xFF;
+       frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
+
+       init_frame->cmd = MFI_CMD_INIT;
+       init_frame->cmd_status = 0xFF;
+
+       init_frame->queue_info_new_phys_addr_lo = ioc_init_handle;
+       init_frame->data_xfer_len = sizeof(struct MPI2_IOC_INIT_REQUEST);
+
+       req_desc =
+         (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)fusion->req_frames_desc;
+
+       req_desc->Words = cmd->frame_phys_addr;
+       req_desc->MFAIo.RequestFlags =
+               (MEGASAS_REQ_DESCRIPT_FLAGS_MFA <<
+                MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+
+       /*
+        * disable the intr before firing the init frame
+        */
+       instance->instancet->disable_intr(instance->reg_set);
+
+       for (i = 0; i < (10 * 1000); i += 20) {
+               if (readl(&instance->reg_set->doorbell) & 1)
+                       msleep(20);
+               else
+                       break;
+       }
+
+       instance->instancet->fire_cmd(instance, req_desc->u.low,
+                                     req_desc->u.high, instance->reg_set);
+
+       wait_and_poll(instance, cmd);
+
+       frame_hdr = &cmd->frame->hdr;
+       if (frame_hdr->cmd_status != 0) {
+               ret = 1;
+               goto fail_fw_init;
+       }
+       printk(KERN_ERR "megasas:IOC Init cmd success\n");
+
+       ret = 0;
+
+fail_fw_init:
+       megasas_return_cmd(instance, cmd);
+       if (IOCInitMessage)
+               dma_free_coherent(&instance->pdev->dev,
+                                 sizeof(struct MPI2_IOC_INIT_REQUEST),
+                                 IOCInitMessage, ioc_init_handle);
+fail_get_cmd:
+       return ret;
+}
+
+/*
+ * megasas_return_cmd_for_smid -       Returns a cmd_fusion for a SMID
+ * @instance:                          Adapter soft state
+ *
+ */
+void
+megasas_return_cmd_for_smid(struct megasas_instance *instance, u16 smid)
+{
+       struct fusion_context *fusion;
+       struct megasas_cmd_fusion *cmd;
+
+       fusion = instance->ctrl_context;
+       cmd = fusion->cmd_list[smid - 1];
+       megasas_return_cmd_fusion(instance, cmd);
+}
+
+/*
+ * megasas_get_ld_map_info -   Returns FW's ld_map structure
+ * @instance:                          Adapter soft state
+ * @pend:                              Pend the command or not
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure.  This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+static int
+megasas_get_ld_map_info(struct megasas_instance *instance)
+{
+       int ret = 0;
+       struct megasas_cmd *cmd;
+       struct megasas_dcmd_frame *dcmd;
+       struct MR_FW_RAID_MAP_ALL *ci;
+       dma_addr_t ci_h = 0;
+       u32 size_map_info;
+       struct fusion_context *fusion;
+
+       cmd = megasas_get_cmd(instance);
+
+       if (!cmd) {
+               printk(KERN_DEBUG "megasas: Failed to get cmd for map info.\n");
+               return -ENOMEM;
+       }
+
+       fusion = instance->ctrl_context;
+
+       if (!fusion) {
+               megasas_return_cmd(instance, cmd);
+               return 1;
+       }
+
+       dcmd = &cmd->frame->dcmd;
+
+       size_map_info = sizeof(struct MR_FW_RAID_MAP) +
+               (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1));
+
+       ci = fusion->ld_map[(instance->map_id & 1)];
+       ci_h = fusion->ld_map_phys[(instance->map_id & 1)];
+
+       if (!ci) {
+               printk(KERN_DEBUG "Failed to alloc mem for ld_map_info\n");
+               megasas_return_cmd(instance, cmd);
+               return -ENOMEM;
+       }
+
+       memset(ci, 0, sizeof(*ci));
+       memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+       dcmd->cmd = MFI_CMD_DCMD;
+       dcmd->cmd_status = 0xFF;
+       dcmd->sge_count = 1;
+       dcmd->flags = MFI_FRAME_DIR_READ;
+       dcmd->timeout = 0;
+       dcmd->pad_0 = 0;
+       dcmd->data_xfer_len = size_map_info;
+       dcmd->opcode = MR_DCMD_LD_MAP_GET_INFO;
+       dcmd->sgl.sge32[0].phys_addr = ci_h;
+       dcmd->sgl.sge32[0].length = size_map_info;
+
+       if (!megasas_issue_polled(instance, cmd))
+               ret = 0;
+       else {
+               printk(KERN_ERR "megasas: Get LD Map Info Failed\n");
+               ret = -1;
+       }
+
+       megasas_return_cmd(instance, cmd);
+
+       return ret;
+}
+
+u8
+megasas_get_map_info(struct megasas_instance *instance)
+{
+       struct fusion_context *fusion = instance->ctrl_context;
+
+       fusion->fast_path_io = 0;
+       if (!megasas_get_ld_map_info(instance)) {
+               if (MR_ValidateMapInfo(fusion->ld_map[(instance->map_id & 1)],
+                                      fusion->load_balance_info)) {
+                       fusion->fast_path_io = 1;
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+/*
+ * megasas_sync_map_info -     Returns FW's ld_map structure
+ * @instance:                          Adapter soft state
+ *
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure.  This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+int
+megasas_sync_map_info(struct megasas_instance *instance)
+{
+       int ret = 0, i;
+       struct megasas_cmd *cmd;
+       struct megasas_dcmd_frame *dcmd;
+       u32 size_sync_info, num_lds;
+       struct fusion_context *fusion;
+       struct MR_LD_TARGET_SYNC *ci = NULL;
+       struct MR_FW_RAID_MAP_ALL *map;
+       struct MR_LD_RAID  *raid;
+       struct MR_LD_TARGET_SYNC *ld_sync;
+       dma_addr_t ci_h = 0;
+       u32 size_map_info;
+
+       cmd = megasas_get_cmd(instance);
+
+       if (!cmd) {
+               printk(KERN_DEBUG "megasas: Failed to get cmd for sync"
+                      "info.\n");
+               return -ENOMEM;
+       }
+
+       fusion = instance->ctrl_context;
+
+       if (!fusion) {
+               megasas_return_cmd(instance, cmd);
+               return 1;
+       }
+
+       map = fusion->ld_map[instance->map_id & 1];
+
+       num_lds = map->raidMap.ldCount;
+
+       dcmd = &cmd->frame->dcmd;
+
+       size_sync_info = sizeof(struct MR_LD_TARGET_SYNC) *num_lds;
+
+       memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+       ci = (struct MR_LD_TARGET_SYNC *)
+         fusion->ld_map[(instance->map_id - 1) & 1];
+       memset(ci, 0, sizeof(struct MR_FW_RAID_MAP_ALL));
+
+       ci_h = fusion->ld_map_phys[(instance->map_id - 1) & 1];
+
+       ld_sync = (struct MR_LD_TARGET_SYNC *)ci;
+
+       for (i = 0; i < num_lds; i++, ld_sync++) {
+               raid = MR_LdRaidGet(i, map);
+               ld_sync->targetId = MR_GetLDTgtId(i, map);
+               ld_sync->seqNum = raid->seqNum;
+       }
+
+       size_map_info = sizeof(struct MR_FW_RAID_MAP) +
+               (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1));
+
+       dcmd->cmd = MFI_CMD_DCMD;
+       dcmd->cmd_status = 0xFF;
+       dcmd->sge_count = 1;
+       dcmd->flags = MFI_FRAME_DIR_WRITE;
+       dcmd->timeout = 0;
+       dcmd->pad_0 = 0;
+       dcmd->data_xfer_len = size_map_info;
+       dcmd->mbox.b[0] = num_lds;
+       dcmd->mbox.b[1] = MEGASAS_DCMD_MBOX_PEND_FLAG;
+       dcmd->opcode = MR_DCMD_LD_MAP_GET_INFO;
+       dcmd->sgl.sge32[0].phys_addr = ci_h;
+       dcmd->sgl.sge32[0].length = size_map_info;
+
+       instance->map_update_cmd = cmd;
+
+       instance->instancet->issue_dcmd(instance, cmd);
+
+       return ret;
+}
+
+/**
+ * megasas_init_adapter_fusion -       Initializes the FW
+ * @instance:          Adapter soft state
+ *
+ * This is the main function for initializing firmware.
+ */
+u32
+megasas_init_adapter_fusion(struct megasas_instance *instance)
+{
+       struct megasas_register_set __iomem *reg_set;
+       struct fusion_context *fusion;
+       u32 max_cmd;
+       int i = 0;
+
+       fusion = instance->ctrl_context;
+
+       reg_set = instance->reg_set;
+
+       /*
+        * Get various operational parameters from status register
+        */
+       instance->max_fw_cmds =
+               instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
+       instance->max_fw_cmds = min(instance->max_fw_cmds, (u16)1008);
+
+       /*
+        * Reduce the max supported cmds by 1. This is to ensure that the
+        * reply_q_sz (1 more than the max cmd that driver may send)
+        * does not exceed max cmds that the FW can support
+        */
+       instance->max_fw_cmds = instance->max_fw_cmds-1;
+       /* Only internal cmds (DCMD) need to have MFI frames */
+       instance->max_mfi_cmds = MEGASAS_INT_CMDS;
+
+       max_cmd = instance->max_fw_cmds;
+
+       fusion->reply_q_depth = ((max_cmd + 1 + 15)/16)*16;
+
+       fusion->request_alloc_sz =
+               sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) *max_cmd;
+       fusion->reply_alloc_sz = sizeof(union MPI2_REPLY_DESCRIPTORS_UNION)
+               *(fusion->reply_q_depth);
+       fusion->io_frames_alloc_sz = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE +
+               (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE *
+                (max_cmd + 1)); /* Extra 1 for SMID 0 */
+
+       fusion->max_sge_in_main_msg =
+         (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
+          offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL))/16;
+
+       fusion->max_sge_in_chain =
+               MEGASAS_MAX_SZ_CHAIN_FRAME / sizeof(union MPI2_SGE_IO_UNION);
+
+       instance->max_num_sge = fusion->max_sge_in_main_msg +
+               fusion->max_sge_in_chain - 2;
+
+       /* Used for pass thru MFI frame (DCMD) */
+       fusion->chain_offset_mfi_pthru =
+               offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL)/16;
+
+       fusion->chain_offset_io_request =
+               (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
+                sizeof(union MPI2_SGE_IO_UNION))/16;
+
+       fusion->last_reply_idx = 0;
+
+       /*
+        * Allocate memory for descriptors
+        * Create a pool of commands
+        */
+       if (megasas_alloc_cmds(instance))
+               goto fail_alloc_mfi_cmds;
+       if (megasas_alloc_cmds_fusion(instance))
+               goto fail_alloc_cmds;
+
+       if (megasas_ioc_init_fusion(instance))
+               goto fail_ioc_init;
+
+       instance->flag_ieee = 1;
+
+       fusion->map_sz =  sizeof(struct MR_FW_RAID_MAP) +
+         (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1));
+
+       fusion->fast_path_io = 0;
+
+       for (i = 0; i < 2; i++) {
+               fusion->ld_map[i] = dma_alloc_coherent(&instance->pdev->dev,
+                                                      fusion->map_sz,
+                                                      &fusion->ld_map_phys[i],
+                                                      GFP_KERNEL);
+               if (!fusion->ld_map[i]) {
+                       printk(KERN_ERR "megasas: Could not allocate memory "
+                              "for map info\n");
+                       goto fail_map_info;
+               }
+       }
+
+       if (!megasas_get_map_info(instance))
+               megasas_sync_map_info(instance);
+
+       return 0;
+
+fail_alloc_cmds:
+fail_alloc_mfi_cmds:
+fail_map_info:
+       if (i == 1)
+               dma_free_coherent(&instance->pdev->dev, fusion->map_sz,
+                                 fusion->ld_map[0], fusion->ld_map_phys[0]);
+fail_ioc_init:
+       return 1;
+}
+
+/**
+ * megasas_fire_cmd_fusion -   Sends command to the FW
+ * @frame_phys_addr :          Physical address of cmd
+ * @frame_count :              Number of frames for the command
+ * @regs :                     MFI register set
+ */
+void
+megasas_fire_cmd_fusion(struct megasas_instance *instance,
+                       dma_addr_t req_desc_lo,
+                       u32 req_desc_hi,
+                       struct megasas_register_set __iomem *regs)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&instance->hba_lock, flags);
+
+       writel(req_desc_lo,
+              &(regs)->inbound_low_queue_port);
+       writel(req_desc_hi, &(regs)->inbound_high_queue_port);
+       spin_unlock_irqrestore(&instance->hba_lock, flags);
+}
+
+/**
+ * map_cmd_status -    Maps FW cmd status to OS cmd status
+ * @cmd :              Pointer to cmd
+ * @status :           status of cmd returned by FW
+ * @ext_status :       ext status of cmd returned by FW
+ */
+
+void
+map_cmd_status(struct megasas_cmd_fusion *cmd, u8 status, u8 ext_status)
+{
+
+       switch (status) {
+
+       case MFI_STAT_OK:
+               cmd->scmd->result = DID_OK << 16;
+               break;
+
+       case MFI_STAT_SCSI_IO_FAILED:
+       case MFI_STAT_LD_INIT_IN_PROGRESS:
+               cmd->scmd->result = (DID_ERROR << 16) | ext_status;
+               break;
+
+       case MFI_STAT_SCSI_DONE_WITH_ERROR:
+
+               cmd->scmd->result = (DID_OK << 16) | ext_status;
+               if (ext_status == SAM_STAT_CHECK_CONDITION) {
+                       memset(cmd->scmd->sense_buffer, 0,
+                              SCSI_SENSE_BUFFERSIZE);
+                       memcpy(cmd->scmd->sense_buffer, cmd->sense,
+                              SCSI_SENSE_BUFFERSIZE);
+                       cmd->scmd->result |= DRIVER_SENSE << 24;
+               }
+               break;
+
+       case MFI_STAT_LD_OFFLINE:
+       case MFI_STAT_DEVICE_NOT_FOUND:
+               cmd->scmd->result = DID_BAD_TARGET << 16;
+               break;
+
+       default:
+               printk(KERN_DEBUG "megasas: FW status %#x\n", status);
+               cmd->scmd->result = DID_ERROR << 16;
+               break;
+       }
+}
+
+/**
+ * megasas_make_sgl_fusion -   Prepares 32-bit SGL
+ * @instance:          Adapter soft state
+ * @scp:               SCSI command from the mid-layer
+ * @sgl_ptr:           SGL to be filled in
+ * @cmd:               cmd we are working on
+ *
+ * If successful, this function returns the number of SG elements.
+ */
+static int
+megasas_make_sgl_fusion(struct megasas_instance *instance,
+                       struct scsi_cmnd *scp,
+                       struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr,
+                       struct megasas_cmd_fusion *cmd)
+{
+       int i, sg_processed;
+       int sge_count, sge_idx;
+       struct scatterlist *os_sgl;
+       struct fusion_context *fusion;
+
+       fusion = instance->ctrl_context;
+
+       cmd->io_request->ChainOffset = 0;
+
+       sge_count = scsi_dma_map(scp);
+
+       BUG_ON(sge_count < 0);
+
+       if (sge_count > instance->max_num_sge || !sge_count)
+               return sge_count;
+
+       if (sge_count > fusion->max_sge_in_main_msg) {
+               /* One element to store the chain info */
+               sge_idx = fusion->max_sge_in_main_msg - 1;
+       } else
+               sge_idx = sge_count;
+
+       scsi_for_each_sg(scp, os_sgl, sge_count, i) {
+               sgl_ptr->Length = sg_dma_len(os_sgl);
+               sgl_ptr->Address = sg_dma_address(os_sgl);
+               sgl_ptr->Flags = 0;
+               sgl_ptr++;
+
+               sg_processed = i + 1;
+
+               if ((sg_processed ==  (fusion->max_sge_in_main_msg - 1)) &&
+                   (sge_count > fusion->max_sge_in_main_msg)) {
+
+                       struct MPI25_IEEE_SGE_CHAIN64 *sg_chain;
+                       cmd->io_request->ChainOffset =
+                               fusion->chain_offset_io_request;
+                       sg_chain = sgl_ptr;
+                       /* Prepare chain element */
+                       sg_chain->NextChainOffset = 0;
+                       sg_chain->Flags = (IEEE_SGE_FLAGS_CHAIN_ELEMENT |
+                                          MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR);
+                       sg_chain->Length =  (sizeof(union MPI2_SGE_IO_UNION)
+                                            *(sge_count - sg_processed));
+                       sg_chain->Address = cmd->sg_frame_phys_addr;
+
+                       sgl_ptr =
+                         (struct MPI25_IEEE_SGE_CHAIN64 *)cmd->sg_frame;
+               }
+       }
+
+       return sge_count;
+}
+
+/**
+ * megasas_set_pd_lba -        Sets PD LBA
+ * @cdb:               CDB
+ * @cdb_len:           cdb length
+ * @start_blk:         Start block of IO
+ *
+ * Used to set the PD LBA in CDB for FP IOs
+ */
+void
+megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len,
+                  struct IO_REQUEST_INFO *io_info, struct scsi_cmnd *scp,
+                  struct MR_FW_RAID_MAP_ALL *local_map_ptr, u32 ref_tag)
+{
+       struct MR_LD_RAID *raid;
+       u32 ld;
+       u64 start_blk = io_info->pdBlock;
+       u8 *cdb = io_request->CDB.CDB32;
+       u32 num_blocks = io_info->numBlocks;
+       u8 opcode, flagvals, groupnum, control;
+
+       /* Check if T10 PI (DIF) is enabled for this LD */
+       ld = MR_TargetIdToLdGet(io_info->ldTgtId, local_map_ptr);
+       raid = MR_LdRaidGet(ld, local_map_ptr);
+       if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) {
+               memset(cdb, 0, sizeof(io_request->CDB.CDB32));
+               cdb[0] =  MEGASAS_SCSI_VARIABLE_LENGTH_CMD;
+               cdb[7] =  MEGASAS_SCSI_ADDL_CDB_LEN;
+
+               if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+                       cdb[9] = MEGASAS_SCSI_SERVICE_ACTION_READ32;
+               else
+                       cdb[9] = MEGASAS_SCSI_SERVICE_ACTION_WRITE32;
+               cdb[10] = MEGASAS_RD_WR_PROTECT_CHECK_ALL;
+
+               /* LBA */
+               cdb[12] = (u8)((start_blk >> 56) & 0xff);
+               cdb[13] = (u8)((start_blk >> 48) & 0xff);
+               cdb[14] = (u8)((start_blk >> 40) & 0xff);
+               cdb[15] = (u8)((start_blk >> 32) & 0xff);
+               cdb[16] = (u8)((start_blk >> 24) & 0xff);
+               cdb[17] = (u8)((start_blk >> 16) & 0xff);
+               cdb[18] = (u8)((start_blk >> 8) & 0xff);
+               cdb[19] = (u8)(start_blk & 0xff);
+
+               /* Logical block reference tag */
+               io_request->CDB.EEDP32.PrimaryReferenceTag =
+                       cpu_to_be32(ref_tag);
+               io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff;
+
+               io_request->DataLength = num_blocks * 512;
+               io_request->IoFlags = 32; /* Specify 32-byte cdb */
+
+               /* Transfer length */
+               cdb[28] = (u8)((num_blocks >> 24) & 0xff);
+               cdb[29] = (u8)((num_blocks >> 16) & 0xff);
+               cdb[30] = (u8)((num_blocks >> 8) & 0xff);
+               cdb[31] = (u8)(num_blocks & 0xff);
+
+               /* set SCSI IO EEDPFlags */
+               if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) {
+                       io_request->EEDPFlags =
+                               MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG  |
+                               MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
+                               MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP |
+                               MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG |
+                               MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
+               } else {
+                       io_request->EEDPFlags =
+                               MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
+                               MPI2_SCSIIO_EEDPFLAGS_INSERT_OP;
+               }
+               io_request->Control |= (0x4 << 26);
+               io_request->EEDPBlockSize = MEGASAS_EEDPBLOCKSIZE;
+       } else {
+               /* Some drives don't support 16/12 byte CDB's, convert to 10 */
+               if (((cdb_len == 12) || (cdb_len == 16)) &&
+                   (start_blk <= 0xffffffff)) {
+                       if (cdb_len == 16) {
+                               opcode = cdb[0] == READ_16 ? READ_10 : WRITE_10;
+                               flagvals = cdb[1];
+                               groupnum = cdb[14];
+                               control = cdb[15];
+                       } else {
+                               opcode = cdb[0] == READ_12 ? READ_10 : WRITE_10;
+                               flagvals = cdb[1];
+                               groupnum = cdb[10];
+                               control = cdb[11];
+                       }
+
+                       memset(cdb, 0, sizeof(io_request->CDB.CDB32));
+
+                       cdb[0] = opcode;
+                       cdb[1] = flagvals;
+                       cdb[6] = groupnum;
+                       cdb[9] = control;
+
+                       /* Transfer length */
+                       cdb[8] = (u8)(num_blocks & 0xff);
+                       cdb[7] = (u8)((num_blocks >> 8) & 0xff);
+
+                       cdb_len = 10;
+               }
+
+               /* Normal case, just load LBA here */
+               switch (cdb_len) {
+               case 6:
+               {
+                       u8 val = cdb[1] & 0xE0;
+                       cdb[3] = (u8)(start_blk & 0xff);
+                       cdb[2] = (u8)((start_blk >> 8) & 0xff);
+                       cdb[1] = val | ((u8)(start_blk >> 16) & 0x1f);
+                       break;
+               }
+               case 10:
+                       cdb[5] = (u8)(start_blk & 0xff);
+                       cdb[4] = (u8)((start_blk >> 8) & 0xff);
+                       cdb[3] = (u8)((start_blk >> 16) & 0xff);
+                       cdb[2] = (u8)((start_blk >> 24) & 0xff);
+                       break;
+               case 12:
+                       cdb[5]    = (u8)(start_blk & 0xff);
+                       cdb[4]    = (u8)((start_blk >> 8) & 0xff);
+                       cdb[3]    = (u8)((start_blk >> 16) & 0xff);
+                       cdb[2]    = (u8)((start_blk >> 24) & 0xff);
+                       break;
+               case 16:
+                       cdb[9]    = (u8)(start_blk & 0xff);
+                       cdb[8]    = (u8)((start_blk >> 8) & 0xff);
+                       cdb[7]    = (u8)((start_blk >> 16) & 0xff);
+                       cdb[6]    = (u8)((start_blk >> 24) & 0xff);
+                       cdb[5]    = (u8)((start_blk >> 32) & 0xff);
+                       cdb[4]    = (u8)((start_blk >> 40) & 0xff);
+                       cdb[3]    = (u8)((start_blk >> 48) & 0xff);
+                       cdb[2]    = (u8)((start_blk >> 56) & 0xff);
+                       break;
+               }
+       }
+}
+
+/**
+ * megasas_build_ldio_fusion - Prepares IOs to devices
+ * @instance:          Adapter soft state
+ * @scp:               SCSI command
+ * @cmd:               Command to be prepared
+ *
+ * Prepares the io_request and chain elements (sg_frame) for IO
+ * The IO can be for PD (Fast Path) or LD
+ */
+void
+megasas_build_ldio_fusion(struct megasas_instance *instance,
+                         struct scsi_cmnd *scp,
+                         struct megasas_cmd_fusion *cmd)
+{
+       u8 fp_possible;
+       u32 start_lba_lo, start_lba_hi, device_id;
+       struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
+       union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+       struct IO_REQUEST_INFO io_info;
+       struct fusion_context *fusion;
+       struct MR_FW_RAID_MAP_ALL *local_map_ptr;
+
+       device_id = MEGASAS_DEV_INDEX(instance, scp);
+
+       fusion = instance->ctrl_context;
+
+       io_request = cmd->io_request;
+       io_request->RaidContext.VirtualDiskTgtId = device_id;
+       io_request->RaidContext.status = 0;
+       io_request->RaidContext.exStatus = 0;
+
+       req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc;
+
+       start_lba_lo = 0;
+       start_lba_hi = 0;
+       fp_possible = 0;
+
+       /*
+        * 6-byte READ(0x08) or WRITE(0x0A) cdb
+        */
+       if (scp->cmd_len == 6) {
+               io_request->DataLength = (u32) scp->cmnd[4];
+               start_lba_lo = ((u32) scp->cmnd[1] << 16) |
+                       ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3];
+
+               start_lba_lo &= 0x1FFFFF;
+       }
+
+       /*
+        * 10-byte READ(0x28) or WRITE(0x2A) cdb
+        */
+       else if (scp->cmd_len == 10) {
+               io_request->DataLength = (u32) scp->cmnd[8] |
+                       ((u32) scp->cmnd[7] << 8);
+               start_lba_lo = ((u32) scp->cmnd[2] << 24) |
+                       ((u32) scp->cmnd[3] << 16) |
+                       ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+       }
+
+       /*
+        * 12-byte READ(0xA8) or WRITE(0xAA) cdb
+        */
+       else if (scp->cmd_len == 12) {
+               io_request->DataLength = ((u32) scp->cmnd[6] << 24) |
+                       ((u32) scp->cmnd[7] << 16) |
+                       ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
+               start_lba_lo = ((u32) scp->cmnd[2] << 24) |
+                       ((u32) scp->cmnd[3] << 16) |
+                       ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+       }
+
+       /*
+        * 16-byte READ(0x88) or WRITE(0x8A) cdb
+        */
+       else if (scp->cmd_len == 16) {
+               io_request->DataLength = ((u32) scp->cmnd[10] << 24) |
+                       ((u32) scp->cmnd[11] << 16) |
+                       ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13];
+               start_lba_lo = ((u32) scp->cmnd[6] << 24) |
+                       ((u32) scp->cmnd[7] << 16) |
+                       ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
+
+               start_lba_hi = ((u32) scp->cmnd[2] << 24) |
+                       ((u32) scp->cmnd[3] << 16) |
+                       ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5];
+       }
+
+       memset(&io_info, 0, sizeof(struct IO_REQUEST_INFO));
+       io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo;
+       io_info.numBlocks = io_request->DataLength;
+       io_info.ldTgtId = device_id;
+
+       if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+               io_info.isRead = 1;
+
+       local_map_ptr = fusion->ld_map[(instance->map_id & 1)];
+
+       if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >=
+            MAX_LOGICAL_DRIVES) || (!fusion->fast_path_io)) {
+               io_request->RaidContext.regLockFlags  = 0;
+               fp_possible = 0;
+       } else {
+               if (MR_BuildRaidContext(&io_info, &io_request->RaidContext,
+                                       local_map_ptr))
+                       fp_possible = io_info.fpOkForIo;
+       }
+
+       if (fp_possible) {
+               megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,
+                                  local_map_ptr, start_lba_lo);
+               io_request->DataLength = scsi_bufflen(scp);
+               io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
+               cmd->request_desc->SCSIIO.RequestFlags =
+                       (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
+                        << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+               if ((fusion->load_balance_info[device_id].loadBalanceFlag) &&
+                   (io_info.isRead)) {
+                       io_info.devHandle =
+                               get_updated_dev_handle(
+                                       &fusion->load_balance_info[device_id],
+                                       &io_info);
+                       scp->SCp.Status |= MEGASAS_LOAD_BALANCE_FLAG;
+               } else
+                       scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
+               cmd->request_desc->SCSIIO.DevHandle = io_info.devHandle;
+               io_request->DevHandle = io_info.devHandle;
+       } else {
+               io_request->RaidContext.timeoutValue =
+                       local_map_ptr->raidMap.fpPdIoTimeoutSec;
+               io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
+               io_request->DevHandle = device_id;
+               cmd->request_desc->SCSIIO.RequestFlags =
+                       (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
+                        << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+       } /* Not FP */
+}
+
+/**
+ * megasas_build_dcdb_fusion - Prepares IOs to devices
+ * @instance:          Adapter soft state
+ * @scp:               SCSI command
+ * @cmd:               Command to be prepared
+ *
+ * Prepares the io_request frame for non-io cmds
+ */
+static void
+megasas_build_dcdb_fusion(struct megasas_instance *instance,
+                         struct scsi_cmnd *scmd,
+                         struct megasas_cmd_fusion *cmd)
+{
+       u32 device_id;
+       struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
+       u16 pd_index = 0;
+       struct MR_FW_RAID_MAP_ALL *local_map_ptr;
+       struct fusion_context *fusion = instance->ctrl_context;
+
+       io_request = cmd->io_request;
+       device_id = MEGASAS_DEV_INDEX(instance, scmd);
+       pd_index = (scmd->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL)
+               +scmd->device->id;
+       local_map_ptr = fusion->ld_map[(instance->map_id & 1)];
+
+       /* Check if this is a system PD I/O */
+       if ((instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) &&
+           (instance->pd_list[pd_index].driveType == TYPE_DISK)) {
+               io_request->Function = 0;
+               io_request->DevHandle =
+                       local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
+               io_request->RaidContext.timeoutValue =
+                       local_map_ptr->raidMap.fpPdIoTimeoutSec;
+               io_request->RaidContext.regLockFlags = 0;
+               io_request->RaidContext.regLockRowLBA = 0;
+               io_request->RaidContext.regLockLength = 0;
+               io_request->RaidContext.RAIDFlags =
+                       MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD <<
+                       MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
+               cmd->request_desc->SCSIIO.RequestFlags =
+                       (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+                        MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+       } else {
+               io_request->Function  = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
+               io_request->DevHandle = device_id;
+               cmd->request_desc->SCSIIO.RequestFlags =
+                       (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
+                        MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+       }
+       io_request->RaidContext.VirtualDiskTgtId = device_id;
+       io_request->LUN[0] = scmd->device->lun;
+       io_request->DataLength = scsi_bufflen(scmd);
+}
+
+/**
+ * megasas_build_io_fusion -   Prepares IOs to devices
+ * @instance:          Adapter soft state
+ * @scp:               SCSI command
+ * @cmd:               Command to be prepared
+ *
+ * Invokes helper functions to prepare request frames
+ * and sets flags appropriate for IO/Non-IO cmd
+ */
+int
+megasas_build_io_fusion(struct megasas_instance *instance,
+                       struct scsi_cmnd *scp,
+                       struct megasas_cmd_fusion *cmd)
+{
+       u32 device_id, sge_count;
+       struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request;
+
+       device_id = MEGASAS_DEV_INDEX(instance, scp);
+
+       /* Zero out some fields so they don't get reused */
+       io_request->LUN[0] = 0;
+       io_request->CDB.EEDP32.PrimaryReferenceTag = 0;
+       io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0;
+       io_request->EEDPFlags = 0;
+       io_request->Control = 0;
+       io_request->EEDPBlockSize = 0;
+       io_request->IoFlags = 0;
+       io_request->RaidContext.RAIDFlags = 0;
+
+       memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len);
+       /*
+        * Just the CDB length,rest of the Flags are zero
+        * This will be modified for FP in build_ldio_fusion
+        */
+       io_request->IoFlags = scp->cmd_len;
+
+       if (megasas_is_ldio(scp))
+               megasas_build_ldio_fusion(instance, scp, cmd);
+       else
+               megasas_build_dcdb_fusion(instance, scp, cmd);
+
+       /*
+        * Construct SGL
+        */
+
+       sge_count =
+               megasas_make_sgl_fusion(instance, scp,
+                                       (struct MPI25_IEEE_SGE_CHAIN64 *)
+                                       &io_request->SGL, cmd);
+
+       if (sge_count > instance->max_num_sge) {
+               printk(KERN_ERR "megasas: Error. sge_count (0x%x) exceeds "
+                      "max (0x%x) allowed\n", sge_count,
+                      instance->max_num_sge);
+               return 1;
+       }
+
+       io_request->RaidContext.numSGE = sge_count;
+
+       io_request->SGLFlags = MPI2_SGE_FLAGS_64_BIT_ADDRESSING;
+
+       if (scp->sc_data_direction == PCI_DMA_TODEVICE)
+               io_request->Control |= MPI2_SCSIIO_CONTROL_WRITE;
+       else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+               io_request->Control |= MPI2_SCSIIO_CONTROL_READ;
+
+       io_request->SGLOffset0 =
+               offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL) / 4;
+
+       io_request->SenseBufferLowAddress = cmd->sense_phys_addr;
+       io_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
+
+       cmd->scmd = scp;
+       scp->SCp.ptr = (char *)cmd;
+
+       return 0;
+}
+
+union MEGASAS_REQUEST_DESCRIPTOR_UNION *
+megasas_get_request_descriptor(struct megasas_instance *instance, u16 index)
+{
+       u8 *p;
+       struct fusion_context *fusion;
+
+       if (index >= instance->max_fw_cmds) {
+               printk(KERN_ERR "megasas: Invalid SMID (0x%x)request for "
+                      "descriptor\n", index);
+               return NULL;
+       }
+       fusion = instance->ctrl_context;
+       p = fusion->req_frames_desc
+               +sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) *index;
+
+       return (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)p;
+}
+
+/**
+ * megasas_build_and_issue_cmd_fusion -Main routine for building and
+ *                                     issuing non IOCTL cmd
+ * @instance:                  Adapter soft state
+ * @scmd:                      pointer to scsi cmd from OS
+ */
+static u32
+megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
+                                  struct scsi_cmnd *scmd)
+{
+       struct megasas_cmd_fusion *cmd;
+       union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+       u32 index;
+       struct fusion_context *fusion;
+
+       fusion = instance->ctrl_context;
+
+       cmd = megasas_get_cmd_fusion(instance);
+       if (!cmd)
+               return SCSI_MLQUEUE_HOST_BUSY;
+
+       index = cmd->index;
+
+       req_desc = megasas_get_request_descriptor(instance, index-1);
+       if (!req_desc)
+               return 1;
+
+       req_desc->Words = 0;
+       cmd->request_desc = req_desc;
+       cmd->request_desc->Words = 0;
+
+       if (megasas_build_io_fusion(instance, scmd, cmd)) {
+               megasas_return_cmd_fusion(instance, cmd);
+               printk(KERN_ERR "megasas: Error building command.\n");
+               cmd->request_desc = NULL;
+               return 1;
+       }
+
+       req_desc = cmd->request_desc;
+       req_desc->SCSIIO.SMID = index;
+
+       if (cmd->io_request->ChainOffset != 0 &&
+           cmd->io_request->ChainOffset != 0xF)
+               printk(KERN_ERR "megasas: The chain offset value is not "
+                      "correct : %x\n", cmd->io_request->ChainOffset);
+
+       /*
+        * Issue the command to the FW
+        */
+       atomic_inc(&instance->fw_outstanding);
+
+       instance->instancet->fire_cmd(instance,
+                                     req_desc->u.low, req_desc->u.high,
+                                     instance->reg_set);
+
+       return 0;
+}
+
+/**
+ * complete_cmd_fusion -       Completes command
+ * @instance:                  Adapter soft state
+ * Completes all commands that is in reply descriptor queue
+ */
+int
+complete_cmd_fusion(struct megasas_instance *instance)
+{
+       union MPI2_REPLY_DESCRIPTORS_UNION *desc;
+       struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *reply_desc;
+       struct MPI2_RAID_SCSI_IO_REQUEST *scsi_io_req;
+       struct fusion_context *fusion;
+       struct megasas_cmd *cmd_mfi;
+       struct megasas_cmd_fusion *cmd_fusion;
+       u16 smid, num_completed;
+       u8 reply_descript_type, arm;
+       u32 status, extStatus, device_id;
+       union desc_value d_val;
+       struct LD_LOAD_BALANCE_INFO *lbinfo;
+
+       fusion = instance->ctrl_context;
+
+       if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
+               return IRQ_HANDLED;
+
+       desc = fusion->reply_frames_desc;
+       desc += fusion->last_reply_idx;
+
+       reply_desc = (struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc;
+
+       d_val.word = desc->Words;
+
+       reply_descript_type = reply_desc->ReplyFlags &
+               MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
+
+       if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
+               return IRQ_NONE;
+
+       d_val.word = desc->Words;
+
+       num_completed = 0;
+
+       while ((d_val.u.low != UINT_MAX) && (d_val.u.high != UINT_MAX)) {
+               smid = reply_desc->SMID;
+
+               cmd_fusion = fusion->cmd_list[smid - 1];
+
+               scsi_io_req =
+                       (struct MPI2_RAID_SCSI_IO_REQUEST *)
+                 cmd_fusion->io_request;
+
+               if (cmd_fusion->scmd)
+                       cmd_fusion->scmd->SCp.ptr = NULL;
+
+               status = scsi_io_req->RaidContext.status;
+               extStatus = scsi_io_req->RaidContext.exStatus;
+
+               switch (scsi_io_req->Function) {
+               case MPI2_FUNCTION_SCSI_IO_REQUEST:  /*Fast Path IO.*/
+                       /* Update load balancing info */
+                       device_id = MEGASAS_DEV_INDEX(instance,
+                                                     cmd_fusion->scmd);
+                       lbinfo = &fusion->load_balance_info[device_id];
+                       if (cmd_fusion->scmd->SCp.Status &
+                           MEGASAS_LOAD_BALANCE_FLAG) {
+                               arm = lbinfo->raid1DevHandle[0] ==
+                                       cmd_fusion->io_request->DevHandle ? 0 :
+                                       1;
+                               atomic_dec(&lbinfo->scsi_pending_cmds[arm]);
+                               cmd_fusion->scmd->SCp.Status &=
+                                       ~MEGASAS_LOAD_BALANCE_FLAG;
+                       }
+                       if (reply_descript_type ==
+                           MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
+                               if (megasas_dbg_lvl == 5)
+                                       printk(KERN_ERR "\nmegasas: FAST Path "
+                                              "IO Success\n");
+                       }
+                       /* Fall thru and complete IO */
+               case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */
+                       /* Map the FW Cmd Status */
+                       map_cmd_status(cmd_fusion, status, extStatus);
+                       scsi_dma_unmap(cmd_fusion->scmd);
+                       cmd_fusion->scmd->scsi_done(cmd_fusion->scmd);
+                       scsi_io_req->RaidContext.status = 0;
+                       scsi_io_req->RaidContext.exStatus = 0;
+                       megasas_return_cmd_fusion(instance, cmd_fusion);
+                       atomic_dec(&instance->fw_outstanding);
+
+                       break;
+               case MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST: /*MFI command */
+                       cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
+                       megasas_complete_cmd(instance, cmd_mfi, DID_OK);
+                       cmd_fusion->flags = 0;
+                       megasas_return_cmd_fusion(instance, cmd_fusion);
+
+                       break;
+               }
+
+               fusion->last_reply_idx++;
+               if (fusion->last_reply_idx >= fusion->reply_q_depth)
+                       fusion->last_reply_idx = 0;
+
+               desc->Words = ULLONG_MAX;
+               num_completed++;
+
+               /* Get the next reply descriptor */
+               if (!fusion->last_reply_idx)
+                       desc = fusion->reply_frames_desc;
+               else
+                       desc++;
+
+               reply_desc =
+                 (struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc;
+
+               d_val.word = desc->Words;
+
+               reply_descript_type = reply_desc->ReplyFlags &
+                       MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
+
+               if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
+                       break;
+       }
+
+       if (!num_completed)
+               return IRQ_NONE;
+
+       wmb();
+       writel(fusion->last_reply_idx,
+              &instance->reg_set->reply_post_host_index);
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * megasas_complete_cmd_dpc_fusion -   Completes command
+ * @instance:                  Adapter soft state
+ *
+ * Tasklet to complete cmds
+ */
+void
+megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
+{
+       struct megasas_instance *instance =
+               (struct megasas_instance *)instance_addr;
+       unsigned long flags;
+
+       /* If we have already declared adapter dead, donot complete cmds */
+       spin_lock_irqsave(&instance->hba_lock, flags);
+       if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+               spin_unlock_irqrestore(&instance->hba_lock, flags);
+               return;
+       }
+       spin_unlock_irqrestore(&instance->hba_lock, flags);
+
+       spin_lock_irqsave(&instance->completion_lock, flags);
+       complete_cmd_fusion(instance);
+       spin_unlock_irqrestore(&instance->completion_lock, flags);
+}
+
+/**
+ * megasas_isr_fusion - isr entry point
+ */
+irqreturn_t megasas_isr_fusion(int irq, void *devp)
+{
+       struct megasas_instance *instance = (struct megasas_instance *)devp;
+       u32 mfiStatus, fw_state;
+
+       if (!instance->msi_flag) {
+               mfiStatus = instance->instancet->clear_intr(instance->reg_set);
+               if (!mfiStatus)
+                       return IRQ_NONE;
+       }
+
+       /* If we are resetting, bail */
+       if (test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags))
+               return IRQ_HANDLED;
+
+       if (!complete_cmd_fusion(instance)) {
+               /* If we didn't complete any commands, check for FW fault */
+               fw_state = instance->instancet->read_fw_status_reg(
+                       instance->reg_set) & MFI_STATE_MASK;
+               if (fw_state == MFI_STATE_FAULT)
+                       schedule_work(&instance->work_init);
+       }
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * build_mpt_mfi_pass_thru - builds a cmd fo MFI Pass thru
+ * @instance:                  Adapter soft state
+ * mfi_cmd:                    megasas_cmd pointer
+ *
+ */
+u8
+build_mpt_mfi_pass_thru(struct megasas_instance *instance,
+                       struct megasas_cmd *mfi_cmd)
+{
+       struct MPI25_IEEE_SGE_CHAIN64 *mpi25_ieee_chain;
+       struct MPI2_RAID_SCSI_IO_REQUEST *io_req;
+       struct megasas_cmd_fusion *cmd;
+       struct fusion_context *fusion;
+       struct megasas_header *frame_hdr = &mfi_cmd->frame->hdr;
+
+       cmd = megasas_get_cmd_fusion(instance);
+       if (!cmd)
+               return 1;
+
+       /*  Save the smid. To be used for returning the cmd */
+       mfi_cmd->context.smid = cmd->index;
+
+       cmd->sync_cmd_idx = mfi_cmd->index;
+
+       /*
+        * For cmds where the flag is set, store the flag and check
+        * on completion. For cmds with this flag, don't call
+        * megasas_complete_cmd
+        */
+
+       if (frame_hdr->flags & MFI_FRAME_DONT_POST_IN_REPLY_QUEUE)
+               cmd->flags = MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
+
+       fusion = instance->ctrl_context;
+       io_req = cmd->io_request;
+       mpi25_ieee_chain =
+         (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL.IeeeChain;
+
+       io_req->Function    = MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST;
+       io_req->SGLOffset0  = offsetof(struct MPI2_RAID_SCSI_IO_REQUEST,
+                                      SGL) / 4;
+       io_req->ChainOffset = fusion->chain_offset_mfi_pthru;
+
+       mpi25_ieee_chain->Address = mfi_cmd->frame_phys_addr;
+
+       mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
+               MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
+
+       mpi25_ieee_chain->Length = MEGASAS_MAX_SZ_CHAIN_FRAME;
+
+       return 0;
+}
+
+/**
+ * build_mpt_cmd - Calls helper function to build a cmd MFI Pass thru cmd
+ * @instance:                  Adapter soft state
+ * @cmd:                       mfi cmd to build
+ *
+ */
+union MEGASAS_REQUEST_DESCRIPTOR_UNION *
+build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
+{
+       union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+       u16 index;
+
+       if (build_mpt_mfi_pass_thru(instance, cmd)) {
+               printk(KERN_ERR "Couldn't build MFI pass thru cmd\n");
+               return NULL;
+       }
+
+       index = cmd->context.smid;
+
+       req_desc = megasas_get_request_descriptor(instance, index - 1);
+
+       if (!req_desc)
+               return NULL;
+
+       req_desc->Words = 0;
+       req_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
+                                        MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+
+       req_desc->SCSIIO.SMID = index;
+
+       return req_desc;
+}
+
+/**
+ * megasas_issue_dcmd_fusion - Issues a MFI Pass thru cmd
+ * @instance:                  Adapter soft state
+ * @cmd:                       mfi cmd pointer
+ *
+ */
+void
+megasas_issue_dcmd_fusion(struct megasas_instance *instance,
+                         struct megasas_cmd *cmd)
+{
+       union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+       union desc_value d_val;
+
+       req_desc = build_mpt_cmd(instance, cmd);
+       if (!req_desc) {
+               printk(KERN_ERR "Couldn't issue MFI pass thru cmd\n");
+               return;
+       }
+       d_val.word = req_desc->Words;
+
+       instance->instancet->fire_cmd(instance, req_desc->u.low,
+                                     req_desc->u.high, instance->reg_set);
+}
+
+/**
+ * megasas_release_fusion -    Reverses the FW initialization
+ * @intance:                   Adapter soft state
+ */
+void
+megasas_release_fusion(struct megasas_instance *instance)
+{
+       megasas_free_cmds(instance);
+       megasas_free_cmds_fusion(instance);
+
+       iounmap(instance->reg_set);
+
+       pci_release_selected_regions(instance->pdev, instance->bar);
+}
+
+/**
+ * megasas_read_fw_status_reg_fusion - returns the current FW status value
+ * @regs:                      MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_fusion(struct megasas_register_set __iomem *regs)
+{
+       return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_adp_reset_fusion -  For controller reset
+ * @regs:                              MFI register set
+ */
+static int
+megasas_adp_reset_fusion(struct megasas_instance *instance,
+                        struct megasas_register_set __iomem *regs)
+{
+       return 0;
+}
+
+/**
+ * megasas_check_reset_fusion -        For controller reset check
+ * @regs:                              MFI register set
+ */
+static int
+megasas_check_reset_fusion(struct megasas_instance *instance,
+                          struct megasas_register_set __iomem *regs)
+{
+       return 0;
+}
+
+/* This function waits for outstanding commands on fusion to complete */
+int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance)
+{
+       int i, outstanding, retval = 0;
+       u32 fw_state, wait_time = MEGASAS_RESET_WAIT_TIME;
+
+       for (i = 0; i < wait_time; i++) {
+               /* Check if firmware is in fault state */
+               fw_state = instance->instancet->read_fw_status_reg(
+                       instance->reg_set) & MFI_STATE_MASK;
+               if (fw_state == MFI_STATE_FAULT) {
+                       printk(KERN_WARNING "megasas: Found FW in FAULT state,"
+                              " will reset adapter.\n");
+                       retval = 1;
+                       goto out;
+               }
+
+               outstanding = atomic_read(&instance->fw_outstanding);
+               if (!outstanding)
+                       goto out;
+
+               if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
+                       printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
+                              "commands to complete\n", i, outstanding);
+                       megasas_complete_cmd_dpc_fusion(
+                               (unsigned long)instance);
+               }
+               msleep(1000);
+       }
+
+       if (atomic_read(&instance->fw_outstanding)) {
+               printk("megaraid_sas: pending commands remain after waiting, "
+                      "will reset adapter.\n");
+               retval = 1;
+       }
+out:
+       return retval;
+}
+
+void  megasas_reset_reply_desc(struct megasas_instance *instance)
+{
+       int i;
+       struct fusion_context *fusion;
+       union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
+
+       fusion = instance->ctrl_context;
+       fusion->last_reply_idx = 0;
+       reply_desc = fusion->reply_frames_desc;
+       for (i = 0 ; i < fusion->reply_q_depth; i++, reply_desc++)
+               reply_desc->Words = ULLONG_MAX;
+}
+
+/* Core fusion reset function */
+int megasas_reset_fusion(struct Scsi_Host *shost)
+{
+       int retval = SUCCESS, i, j, retry = 0;
+       struct megasas_instance *instance;
+       struct megasas_cmd_fusion *cmd_fusion;
+       struct fusion_context *fusion;
+       struct megasas_cmd *cmd_mfi;
+       union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+       u32 host_diag, abs_state;
+
+       instance = (struct megasas_instance *)shost->hostdata;
+       fusion = instance->ctrl_context;
+
+       mutex_lock(&instance->reset_mutex);
+       set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+       instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
+       instance->instancet->disable_intr(instance->reg_set);
+       msleep(1000);
+
+       if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+               printk(KERN_WARNING "megaraid_sas: Hardware critical error, "
+                      "returning FAILED.\n");
+               retval = FAILED;
+               goto out;
+       }
+
+       /* First try waiting for commands to complete */
+       if (megasas_wait_for_outstanding_fusion(instance)) {
+               printk(KERN_WARNING "megaraid_sas: resetting fusion "
+                      "adapter.\n");
+               /* Now return commands back to the OS */
+               for (i = 0 ; i < instance->max_fw_cmds; i++) {
+                       cmd_fusion = fusion->cmd_list[i];
+                       if (cmd_fusion->scmd) {
+                               scsi_dma_unmap(cmd_fusion->scmd);
+                               cmd_fusion->scmd->result = (DID_RESET << 16);
+                               cmd_fusion->scmd->scsi_done(cmd_fusion->scmd);
+                               megasas_return_cmd_fusion(instance, cmd_fusion);
+                               atomic_dec(&instance->fw_outstanding);
+                       }
+               }
+
+               if (instance->disableOnlineCtrlReset == 1) {
+                       /* Reset not supported, kill adapter */
+                       printk(KERN_WARNING "megaraid_sas: Reset not supported"
+                              ", killing adapter.\n");
+                       megaraid_sas_kill_hba(instance);
+                       instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
+                       retval = FAILED;
+                       goto out;
+               }
+
+               /* Now try to reset the chip */
+               for (i = 0; i < MEGASAS_FUSION_MAX_RESET_TRIES; i++) {
+                       writel(MPI2_WRSEQ_FLUSH_KEY_VALUE,
+                              &instance->reg_set->fusion_seq_offset);
+                       writel(MPI2_WRSEQ_1ST_KEY_VALUE,
+                              &instance->reg_set->fusion_seq_offset);
+                       writel(MPI2_WRSEQ_2ND_KEY_VALUE,
+                              &instance->reg_set->fusion_seq_offset);
+                       writel(MPI2_WRSEQ_3RD_KEY_VALUE,
+                              &instance->reg_set->fusion_seq_offset);
+                       writel(MPI2_WRSEQ_4TH_KEY_VALUE,
+                              &instance->reg_set->fusion_seq_offset);
+                       writel(MPI2_WRSEQ_5TH_KEY_VALUE,
+                              &instance->reg_set->fusion_seq_offset);
+                       writel(MPI2_WRSEQ_6TH_KEY_VALUE,
+                              &instance->reg_set->fusion_seq_offset);
+
+                       /* Check that the diag write enable (DRWE) bit is on */
+                       host_diag = readl(&instance->reg_set->fusion_host_diag);
+                       while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
+                               msleep(100);
+                               host_diag =
+                               readl(&instance->reg_set->fusion_host_diag);
+                               if (retry++ == 100) {
+                                       printk(KERN_WARNING "megaraid_sas: "
+                                              "Host diag unlock failed!\n");
+                                       break;
+                               }
+                       }
+                       if (!(host_diag & HOST_DIAG_WRITE_ENABLE))
+                               continue;
+
+                       /* Send chip reset command */
+                       writel(host_diag | HOST_DIAG_RESET_ADAPTER,
+                              &instance->reg_set->fusion_host_diag);
+                       msleep(3000);
+
+                       /* Make sure reset adapter bit is cleared */
+                       host_diag = readl(&instance->reg_set->fusion_host_diag);
+                       retry = 0;
+                       while (host_diag & HOST_DIAG_RESET_ADAPTER) {
+                               msleep(100);
+                               host_diag =
+                               readl(&instance->reg_set->fusion_host_diag);
+                               if (retry++ == 1000) {
+                                       printk(KERN_WARNING "megaraid_sas: "
+                                              "Diag reset adapter never "
+                                              "cleared!\n");
+                                       break;
+                               }
+                       }
+                       if (host_diag & HOST_DIAG_RESET_ADAPTER)
+                               continue;
+
+                       abs_state =
+                               instance->instancet->read_fw_status_reg(
+                                       instance->reg_set);
+                       retry = 0;
+
+                       while ((abs_state <= MFI_STATE_FW_INIT) &&
+                              (retry++ < 1000)) {
+                               msleep(100);
+                               abs_state =
+                               instance->instancet->read_fw_status_reg(
+                                       instance->reg_set);
+                       }
+                       if (abs_state <= MFI_STATE_FW_INIT) {
+                               printk(KERN_WARNING "megaraid_sas: firmware "
+                                      "state < MFI_STATE_FW_INIT, state = "
+                                      "0x%x\n", abs_state);
+                               continue;
+                       }
+
+                       /* Wait for FW to become ready */
+                       if (megasas_transition_to_ready(instance)) {
+                               printk(KERN_WARNING "megaraid_sas: Failed to "
+                                      "transition controller to ready.\n");
+                               continue;
+                       }
+
+                       megasas_reset_reply_desc(instance);
+                       if (megasas_ioc_init_fusion(instance)) {
+                               printk(KERN_WARNING "megaraid_sas: "
+                                      "megasas_ioc_init_fusion() failed!\n");
+                               continue;
+                       }
+
+                       instance->instancet->enable_intr(instance->reg_set);
+                       instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
+
+                       /* Re-fire management commands */
+                       for (j = 0 ; j < instance->max_fw_cmds; j++) {
+                               cmd_fusion = fusion->cmd_list[j];
+                               if (cmd_fusion->sync_cmd_idx !=
+                                   (u32)ULONG_MAX) {
+                                       cmd_mfi =
+                                       instance->
+                                       cmd_list[cmd_fusion->sync_cmd_idx];
+                                       if (cmd_mfi->frame->dcmd.opcode ==
+                                           MR_DCMD_LD_MAP_GET_INFO) {
+                                               megasas_return_cmd(instance,
+                                                                  cmd_mfi);
+                                               megasas_return_cmd_fusion(
+                                                       instance, cmd_fusion);
+                                       } else  {
+                                               req_desc =
+                                               megasas_get_request_descriptor(
+                                                       instance,
+                                                       cmd_mfi->context.smid
+                                                       -1);
+                                               if (!req_desc)
+                                                       printk(KERN_WARNING
+                                                              "req_desc NULL"
+                                                              "\n");
+                                               else {
+                                                       instance->instancet->
+                                                       fire_cmd(instance,
+                                                                req_desc->
+                                                                u.low,
+                                                                req_desc->
+                                                                u.high,
+                                                                instance->
+                                                                reg_set);
+                                               }
+                                       }
+                               }
+                       }
+
+                       /* Reset load balance info */
+                       memset(fusion->load_balance_info, 0,
+                              sizeof(struct LD_LOAD_BALANCE_INFO)
+                              *MAX_LOGICAL_DRIVES);
+
+                       if (!megasas_get_map_info(instance))
+                               megasas_sync_map_info(instance);
+
+                       /* Adapter reset completed successfully */
+                       printk(KERN_WARNING "megaraid_sas: Reset "
+                              "successful.\n");
+                       retval = SUCCESS;
+                       goto out;
+               }
+               /* Reset failed, kill the adapter */
+               printk(KERN_WARNING "megaraid_sas: Reset failed, killing "
+                      "adapter.\n");
+               megaraid_sas_kill_hba(instance);
+               retval = FAILED;
+       } else {
+               instance->instancet->enable_intr(instance->reg_set);
+               instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
+       }
+out:
+       clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+       mutex_unlock(&instance->reset_mutex);
+       return retval;
+}
+
+/* Fusion OCR work queue */
+void megasas_fusion_ocr_wq(struct work_struct *work)
+{
+       struct megasas_instance *instance =
+               container_of(work, struct megasas_instance, work_init);
+
+       megasas_reset_fusion(instance->host);
+}
+
+struct megasas_instance_template megasas_instance_template_fusion = {
+       .fire_cmd = megasas_fire_cmd_fusion,
+       .enable_intr = megasas_enable_intr_fusion,
+       .disable_intr = megasas_disable_intr_fusion,
+       .clear_intr = megasas_clear_intr_fusion,
+       .read_fw_status_reg = megasas_read_fw_status_reg_fusion,
+       .adp_reset = megasas_adp_reset_fusion,
+       .check_reset = megasas_check_reset_fusion,
+       .service_isr = megasas_isr_fusion,
+       .tasklet = megasas_complete_cmd_dpc_fusion,
+       .init_adapter = megasas_init_adapter_fusion,
+       .build_and_issue_cmd = megasas_build_and_issue_cmd_fusion,
+       .issue_dcmd = megasas_issue_dcmd_fusion,
+};
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
new file mode 100644 (file)
index 0000000..82b577a
--- /dev/null
@@ -0,0 +1,695 @@
+/*
+ *  Linux MegaRAID driver for SAS based RAID controllers
+ *
+ *  Copyright (c) 2009-2011  LSI Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *  FILE: megaraid_sas_fusion.h
+ *
+ *  Authors: LSI Corporation
+ *           Manoj Jose
+ *           Sumant Patro
+ *
+ *  Send feedback to: <megaraidlinux@lsi.com>
+ *
+ *  Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ *     ATTN: Linuxraid
+ */
+
+#ifndef _MEGARAID_SAS_FUSION_H_
+#define _MEGARAID_SAS_FUSION_H_
+
+/* Fusion defines */
+#define MEGASAS_MAX_SZ_CHAIN_FRAME 1024
+#define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000009)
+#define MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE 256
+#define MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST   0xF0
+#define MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST         0xF1
+#define MEGASAS_LOAD_BALANCE_FLAG                  0x1
+#define MEGASAS_DCMD_MBOX_PEND_FLAG                0x1
+#define HOST_DIAG_WRITE_ENABLE                     0x80
+#define HOST_DIAG_RESET_ADAPTER                            0x4
+#define MEGASAS_FUSION_MAX_RESET_TRIES             3
+
+/* T10 PI defines */
+#define MR_PROT_INFO_TYPE_CONTROLLER                0x8
+#define MEGASAS_SCSI_VARIABLE_LENGTH_CMD            0x7f
+#define MEGASAS_SCSI_SERVICE_ACTION_READ32          0x9
+#define MEGASAS_SCSI_SERVICE_ACTION_WRITE32         0xB
+#define MEGASAS_SCSI_ADDL_CDB_LEN                   0x18
+#define MEGASAS_RD_WR_PROTECT_CHECK_ALL                    0x20
+#define MEGASAS_RD_WR_PROTECT_CHECK_NONE           0x60
+#define MEGASAS_EEDPBLOCKSIZE                      512
+
+/*
+ * Raid context flags
+ */
+
+#define MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT   0x4
+#define MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_MASK    0x30
+enum MR_RAID_FLAGS_IO_SUB_TYPE {
+       MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0,
+       MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1,
+};
+
+/*
+ * Request descriptor types
+ */
+#define MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO           0x7
+#define MEGASAS_REQ_DESCRIPT_FLAGS_MFA             0x1
+
+#define MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT      1
+
+#define MEGASAS_FP_CMD_LEN     16
+#define MEGASAS_FUSION_IN_RESET 0
+
+/*
+ * Raid Context structure which describes MegaRAID specific IO Paramenters
+ * This resides at offset 0x60 where the SGL normally starts in MPT IO Frames
+ */
+
+struct RAID_CONTEXT {
+       u16     resvd0;
+       u16     timeoutValue;
+       u8      regLockFlags;
+       u8      resvd1;
+       u16     VirtualDiskTgtId;
+       u64     regLockRowLBA;
+       u32     regLockLength;
+       u16     nextLMId;
+       u8      exStatus;
+       u8      status;
+       u8      RAIDFlags;
+       u8      numSGE;
+       u16     configSeqNum;
+       u8      spanArm;
+       u8      resvd2[3];
+};
+
+#define RAID_CTX_SPANARM_ARM_SHIFT     (0)
+#define RAID_CTX_SPANARM_ARM_MASK      (0x1f)
+
+#define RAID_CTX_SPANARM_SPAN_SHIFT    (5)
+#define RAID_CTX_SPANARM_SPAN_MASK     (0xE0)
+
+/*
+ * define region lock types
+ */
+enum REGION_TYPE {
+       REGION_TYPE_UNUSED       = 0,
+       REGION_TYPE_SHARED_READ  = 1,
+       REGION_TYPE_SHARED_WRITE = 2,
+       REGION_TYPE_EXCLUSIVE    = 3,
+};
+
+/* MPI2 defines */
+#define MPI2_FUNCTION_IOC_INIT              (0x02) /* IOC Init */
+#define MPI2_WHOINIT_HOST_DRIVER            (0x04)
+#define MPI2_VERSION_MAJOR                  (0x02)
+#define MPI2_VERSION_MINOR                  (0x00)
+#define MPI2_VERSION_MAJOR_MASK             (0xFF00)
+#define MPI2_VERSION_MAJOR_SHIFT            (8)
+#define MPI2_VERSION_MINOR_MASK             (0x00FF)
+#define MPI2_VERSION_MINOR_SHIFT            (0)
+#define MPI2_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \
+                     MPI2_VERSION_MINOR)
+#define MPI2_HEADER_VERSION_UNIT            (0x10)
+#define MPI2_HEADER_VERSION_DEV             (0x00)
+#define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
+#define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
+#define MPI2_HEADER_VERSION_DEV_MASK        (0x00FF)
+#define MPI2_HEADER_VERSION_DEV_SHIFT       (0)
+#define MPI2_HEADER_VERSION ((MPI2_HEADER_VERSION_UNIT << 8) | \
+                            MPI2_HEADER_VERSION_DEV)
+#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR      (0x03)
+#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG        (0x8000)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG          (0x0400)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP       (0x0003)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG          (0x0200)
+#define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD           (0x0100)
+#define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP             (0x0004)
+#define MPI2_FUNCTION_SCSI_IO_REQUEST               (0x00) /* SCSI IO */
+#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY           (0x06)
+#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO                 (0x00)
+#define MPI2_SGE_FLAGS_64_BIT_ADDRESSING        (0x02)
+#define MPI2_SCSIIO_CONTROL_WRITE               (0x01000000)
+#define MPI2_SCSIIO_CONTROL_READ                (0x02000000)
+#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK       (0x0E)
+#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED          (0x0F)
+#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00)
+#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK       (0x0F)
+#define MPI2_WRSEQ_FLUSH_KEY_VALUE              (0x0)
+#define MPI2_WRITE_SEQUENCE_OFFSET              (0x00000004)
+#define MPI2_WRSEQ_1ST_KEY_VALUE                (0xF)
+#define MPI2_WRSEQ_2ND_KEY_VALUE                (0x4)
+#define MPI2_WRSEQ_3RD_KEY_VALUE                (0xB)
+#define MPI2_WRSEQ_4TH_KEY_VALUE                (0x2)
+#define MPI2_WRSEQ_5TH_KEY_VALUE                (0x7)
+#define MPI2_WRSEQ_6TH_KEY_VALUE                (0xD)
+
+struct MPI25_IEEE_SGE_CHAIN64 {
+       u64                     Address;
+       u32                     Length;
+       u16                     Reserved1;
+       u8                      NextChainOffset;
+       u8                      Flags;
+};
+
+struct MPI2_SGE_SIMPLE_UNION {
+       u32                     FlagsLength;
+       union {
+               u32                 Address32;
+               u64                 Address64;
+       } u;
+};
+
+struct MPI2_SCSI_IO_CDB_EEDP32 {
+       u8                      CDB[20];                    /* 0x00 */
+       u32                     PrimaryReferenceTag;        /* 0x14 */
+       u16                     PrimaryApplicationTag;      /* 0x18 */
+       u16                     PrimaryApplicationTagMask;  /* 0x1A */
+       u32                     TransferLength;             /* 0x1C */
+};
+
+struct MPI2_SGE_CHAIN_UNION {
+       u16                     Length;
+       u8                      NextChainOffset;
+       u8                      Flags;
+       union {
+               u32                 Address32;
+               u64                 Address64;
+       } u;
+};
+
+struct MPI2_IEEE_SGE_SIMPLE32 {
+       u32                     Address;
+       u32                     FlagsLength;
+};
+
+struct MPI2_IEEE_SGE_CHAIN32 {
+       u32                     Address;
+       u32                     FlagsLength;
+};
+
+struct MPI2_IEEE_SGE_SIMPLE64 {
+       u64                     Address;
+       u32                     Length;
+       u16                     Reserved1;
+       u8                      Reserved2;
+       u8                      Flags;
+};
+
+struct MPI2_IEEE_SGE_CHAIN64 {
+       u64                     Address;
+       u32                     Length;
+       u16                     Reserved1;
+       u8                      Reserved2;
+       u8                      Flags;
+};
+
+union MPI2_IEEE_SGE_SIMPLE_UNION {
+       struct MPI2_IEEE_SGE_SIMPLE32  Simple32;
+       struct MPI2_IEEE_SGE_SIMPLE64  Simple64;
+};
+
+union MPI2_IEEE_SGE_CHAIN_UNION {
+       struct MPI2_IEEE_SGE_CHAIN32   Chain32;
+       struct MPI2_IEEE_SGE_CHAIN64   Chain64;
+};
+
+union MPI2_SGE_IO_UNION {
+       struct MPI2_SGE_SIMPLE_UNION       MpiSimple;
+       struct MPI2_SGE_CHAIN_UNION        MpiChain;
+       union MPI2_IEEE_SGE_SIMPLE_UNION  IeeeSimple;
+       union MPI2_IEEE_SGE_CHAIN_UNION   IeeeChain;
+};
+
+union MPI2_SCSI_IO_CDB_UNION {
+       u8                      CDB32[32];
+       struct MPI2_SCSI_IO_CDB_EEDP32 EEDP32;
+       struct MPI2_SGE_SIMPLE_UNION SGE;
+};
+
+/*
+ * RAID SCSI IO Request Message
+ * Total SGE count will be one less than  _MPI2_SCSI_IO_REQUEST
+ */
+struct MPI2_RAID_SCSI_IO_REQUEST {
+       u16                     DevHandle;                      /* 0x00 */
+       u8                      ChainOffset;                    /* 0x02 */
+       u8                      Function;                       /* 0x03 */
+       u16                     Reserved1;                      /* 0x04 */
+       u8                      Reserved2;                      /* 0x06 */
+       u8                      MsgFlags;                       /* 0x07 */
+       u8                      VP_ID;                          /* 0x08 */
+       u8                      VF_ID;                          /* 0x09 */
+       u16                     Reserved3;                      /* 0x0A */
+       u32                     SenseBufferLowAddress;          /* 0x0C */
+       u16                     SGLFlags;                       /* 0x10 */
+       u8                      SenseBufferLength;              /* 0x12 */
+       u8                      Reserved4;                      /* 0x13 */
+       u8                      SGLOffset0;                     /* 0x14 */
+       u8                      SGLOffset1;                     /* 0x15 */
+       u8                      SGLOffset2;                     /* 0x16 */
+       u8                      SGLOffset3;                     /* 0x17 */
+       u32                     SkipCount;                      /* 0x18 */
+       u32                     DataLength;                     /* 0x1C */
+       u32                     BidirectionalDataLength;        /* 0x20 */
+       u16                     IoFlags;                        /* 0x24 */
+       u16                     EEDPFlags;                      /* 0x26 */
+       u32                     EEDPBlockSize;                  /* 0x28 */
+       u32                     SecondaryReferenceTag;          /* 0x2C */
+       u16                     SecondaryApplicationTag;        /* 0x30 */
+       u16                     ApplicationTagTranslationMask;  /* 0x32 */
+       u8                      LUN[8];                         /* 0x34 */
+       u32                     Control;                        /* 0x3C */
+       union MPI2_SCSI_IO_CDB_UNION  CDB;                      /* 0x40 */
+       struct RAID_CONTEXT     RaidContext;                    /* 0x60 */
+       union MPI2_SGE_IO_UNION       SGL;                      /* 0x80 */
+};
+
+/*
+ * MPT RAID MFA IO Descriptor.
+ */
+struct MEGASAS_RAID_MFA_IO_REQUEST_DESCRIPTOR {
+       u32     RequestFlags:8;
+       u32     MessageAddress1:24; /* bits 31:8*/
+       u32     MessageAddress2;      /* bits 61:32 */
+};
+
+/* Default Request Descriptor */
+struct MPI2_DEFAULT_REQUEST_DESCRIPTOR {
+       u8              RequestFlags;               /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u16             LMID;                       /* 0x04 */
+       u16             DescriptorTypeDependent;    /* 0x06 */
+};
+
+/* High Priority Request Descriptor */
+struct MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR {
+       u8              RequestFlags;               /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u16             LMID;                       /* 0x04 */
+       u16             Reserved1;                  /* 0x06 */
+};
+
+/* SCSI IO Request Descriptor */
+struct MPI2_SCSI_IO_REQUEST_DESCRIPTOR {
+       u8              RequestFlags;               /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u16             LMID;                       /* 0x04 */
+       u16             DevHandle;                  /* 0x06 */
+};
+
+/* SCSI Target Request Descriptor */
+struct MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR {
+       u8              RequestFlags;               /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u16             LMID;                       /* 0x04 */
+       u16             IoIndex;                    /* 0x06 */
+};
+
+/* RAID Accelerator Request Descriptor */
+struct MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR {
+       u8              RequestFlags;               /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u16             LMID;                       /* 0x04 */
+       u16             Reserved;                   /* 0x06 */
+};
+
+/* union of Request Descriptors */
+union MEGASAS_REQUEST_DESCRIPTOR_UNION {
+       struct MPI2_DEFAULT_REQUEST_DESCRIPTOR             Default;
+       struct MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR       HighPriority;
+       struct MPI2_SCSI_IO_REQUEST_DESCRIPTOR             SCSIIO;
+       struct MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR         SCSITarget;
+       struct MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR          RAIDAccelerator;
+       struct MEGASAS_RAID_MFA_IO_REQUEST_DESCRIPTOR      MFAIo;
+       union {
+               struct {
+                       u32 low;
+                       u32 high;
+               } u;
+               u64 Words;
+       };
+};
+
+/* Default Reply Descriptor */
+struct MPI2_DEFAULT_REPLY_DESCRIPTOR {
+       u8              ReplyFlags;                 /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             DescriptorTypeDependent1;   /* 0x02 */
+       u32             DescriptorTypeDependent2;   /* 0x04 */
+};
+
+/* Address Reply Descriptor */
+struct MPI2_ADDRESS_REPLY_DESCRIPTOR {
+       u8              ReplyFlags;                 /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u32             ReplyFrameAddress;          /* 0x04 */
+};
+
+/* SCSI IO Success Reply Descriptor */
+struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR {
+       u8              ReplyFlags;                 /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u16             TaskTag;                    /* 0x04 */
+       u16             Reserved1;                  /* 0x06 */
+};
+
+/* TargetAssist Success Reply Descriptor */
+struct MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR {
+       u8              ReplyFlags;                 /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u8              SequenceNumber;             /* 0x04 */
+       u8              Reserved1;                  /* 0x05 */
+       u16             IoIndex;                    /* 0x06 */
+};
+
+/* Target Command Buffer Reply Descriptor */
+struct MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR {
+       u8              ReplyFlags;                 /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u8              VP_ID;                      /* 0x02 */
+       u8              Flags;                      /* 0x03 */
+       u16             InitiatorDevHandle;         /* 0x04 */
+       u16             IoIndex;                    /* 0x06 */
+};
+
+/* RAID Accelerator Success Reply Descriptor */
+struct MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR {
+       u8              ReplyFlags;                 /* 0x00 */
+       u8              MSIxIndex;                  /* 0x01 */
+       u16             SMID;                       /* 0x02 */
+       u32             Reserved;                   /* 0x04 */
+};
+
+/* union of Reply Descriptors */
+union MPI2_REPLY_DESCRIPTORS_UNION {
+       struct MPI2_DEFAULT_REPLY_DESCRIPTOR                   Default;
+       struct MPI2_ADDRESS_REPLY_DESCRIPTOR                   AddressReply;
+       struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR           SCSIIOSuccess;
+       struct MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess;
+       struct MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
+       struct MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR
+       RAIDAcceleratorSuccess;
+       u64                                             Words;
+};
+
+/* IOCInit Request message */
+struct MPI2_IOC_INIT_REQUEST {
+       u8                      WhoInit;                        /* 0x00 */
+       u8                      Reserved1;                      /* 0x01 */
+       u8                      ChainOffset;                    /* 0x02 */
+       u8                      Function;                       /* 0x03 */
+       u16                     Reserved2;                      /* 0x04 */
+       u8                      Reserved3;                      /* 0x06 */
+       u8                      MsgFlags;                       /* 0x07 */
+       u8                      VP_ID;                          /* 0x08 */
+       u8                      VF_ID;                          /* 0x09 */
+       u16                     Reserved4;                      /* 0x0A */
+       u16                     MsgVersion;                     /* 0x0C */
+       u16                     HeaderVersion;                  /* 0x0E */
+       u32                     Reserved5;                      /* 0x10 */
+       u16                     Reserved6;                      /* 0x14 */
+       u8                      Reserved7;                      /* 0x16 */
+       u8                      HostMSIxVectors;                /* 0x17 */
+       u16                     Reserved8;                      /* 0x18 */
+       u16                     SystemRequestFrameSize;         /* 0x1A */
+       u16                     ReplyDescriptorPostQueueDepth;  /* 0x1C */
+       u16                     ReplyFreeQueueDepth;            /* 0x1E */
+       u32                     SenseBufferAddressHigh;         /* 0x20 */
+       u32                     SystemReplyAddressHigh;         /* 0x24 */
+       u64                     SystemRequestFrameBaseAddress;  /* 0x28 */
+       u64                     ReplyDescriptorPostQueueAddress;/* 0x30 */
+       u64                     ReplyFreeQueueAddress;          /* 0x38 */
+       u64                     TimeStamp;                      /* 0x40 */
+};
+
+/* mrpriv defines */
+#define MR_PD_INVALID 0xFFFF
+#define MAX_SPAN_DEPTH 8
+#define MAX_RAIDMAP_SPAN_DEPTH (MAX_SPAN_DEPTH)
+#define MAX_ROW_SIZE 32
+#define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE)
+#define MAX_LOGICAL_DRIVES 64
+#define MAX_RAIDMAP_LOGICAL_DRIVES (MAX_LOGICAL_DRIVES)
+#define MAX_RAIDMAP_VIEWS (MAX_LOGICAL_DRIVES)
+#define MAX_ARRAYS 128
+#define MAX_RAIDMAP_ARRAYS (MAX_ARRAYS)
+#define MAX_PHYSICAL_DEVICES 256
+#define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
+#define MR_DCMD_LD_MAP_GET_INFO             0x0300e101
+
+struct MR_DEV_HANDLE_INFO {
+       u16     curDevHdl;
+       u8      validHandles;
+       u8      reserved;
+       u16     devHandle[2];
+};
+
+struct MR_ARRAY_INFO {
+       u16      pd[MAX_RAIDMAP_ROW_SIZE];
+};
+
+struct MR_QUAD_ELEMENT {
+       u64     logStart;
+       u64     logEnd;
+       u64     offsetInSpan;
+       u32     diff;
+       u32     reserved1;
+};
+
+struct MR_SPAN_INFO {
+       u32             noElements;
+       u32             reserved1;
+       struct MR_QUAD_ELEMENT quad[MAX_RAIDMAP_SPAN_DEPTH];
+};
+
+struct MR_LD_SPAN {
+       u64      startBlk;
+       u64      numBlks;
+       u16      arrayRef;
+       u8       reserved[6];
+};
+
+struct MR_SPAN_BLOCK_INFO {
+       u64          num_rows;
+       struct MR_LD_SPAN   span;
+       struct MR_SPAN_INFO block_span_info;
+};
+
+struct MR_LD_RAID {
+       struct {
+               u32     fpCapable:1;
+               u32     reserved5:3;
+               u32     ldPiMode:4;
+               u32     pdPiMode:4;
+               u32     encryptionType:8;
+               u32     fpWriteCapable:1;
+               u32     fpReadCapable:1;
+               u32     fpWriteAcrossStripe:1;
+               u32     fpReadAcrossStripe:1;
+               u32     reserved4:8;
+       } capability;
+       u32     reserved6;
+       u64     size;
+       u8      spanDepth;
+       u8      level;
+       u8      stripeShift;
+       u8      rowSize;
+       u8      rowDataSize;
+       u8      writeMode;
+       u8      PRL;
+       u8      SRL;
+       u16     targetId;
+       u8      ldState;
+       u8      regTypeReqOnWrite;
+       u8      modFactor;
+       u8      reserved2[1];
+       u16     seqNum;
+
+       struct {
+               u32 ldSyncRequired:1;
+               u32 reserved:31;
+       } flags;
+
+       u8      reserved3[0x5C];
+};
+
+struct MR_LD_SPAN_MAP {
+       struct MR_LD_RAID          ldRaid;
+       u8                  dataArmMap[MAX_RAIDMAP_ROW_SIZE];
+       struct MR_SPAN_BLOCK_INFO  spanBlock[MAX_RAIDMAP_SPAN_DEPTH];
+};
+
+struct MR_FW_RAID_MAP {
+       u32                 totalSize;
+       union {
+               struct {
+                       u32         maxLd;
+                       u32         maxSpanDepth;
+                       u32         maxRowSize;
+                       u32         maxPdCount;
+                       u32         maxArrays;
+               } validationInfo;
+               u32             version[5];
+               u32             reserved1[5];
+       };
+
+       u32                 ldCount;
+       u32                 Reserved1;
+       u8                  ldTgtIdToLd[MAX_RAIDMAP_LOGICAL_DRIVES+
+                                       MAX_RAIDMAP_VIEWS];
+       u8                  fpPdIoTimeoutSec;
+       u8                  reserved2[7];
+       struct MR_ARRAY_INFO       arMapInfo[MAX_RAIDMAP_ARRAYS];
+       struct MR_DEV_HANDLE_INFO  devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
+       struct MR_LD_SPAN_MAP      ldSpanMap[1];
+};
+
+struct IO_REQUEST_INFO {
+       u64 ldStartBlock;
+       u32 numBlocks;
+       u16 ldTgtId;
+       u8 isRead;
+       u16 devHandle;
+       u64 pdBlock;
+       u8 fpOkForIo;
+};
+
+struct MR_LD_TARGET_SYNC {
+       u8  targetId;
+       u8  reserved;
+       u16 seqNum;
+};
+
+#define IEEE_SGE_FLAGS_ADDR_MASK            (0x03)
+#define IEEE_SGE_FLAGS_SYSTEM_ADDR          (0x00)
+#define IEEE_SGE_FLAGS_IOCDDR_ADDR          (0x01)
+#define IEEE_SGE_FLAGS_IOCPLB_ADDR          (0x02)
+#define IEEE_SGE_FLAGS_IOCPLBNTA_ADDR       (0x03)
+#define IEEE_SGE_FLAGS_CHAIN_ELEMENT        (0x80)
+#define IEEE_SGE_FLAGS_END_OF_LIST          (0x40)
+
+struct megasas_register_set;
+struct megasas_instance;
+
+union desc_word {
+       u64 word;
+       struct {
+               u32 low;
+               u32 high;
+       } u;
+};
+
+struct megasas_cmd_fusion {
+       struct MPI2_RAID_SCSI_IO_REQUEST        *io_request;
+       dma_addr_t                      io_request_phys_addr;
+
+       union MPI2_SGE_IO_UNION *sg_frame;
+       dma_addr_t              sg_frame_phys_addr;
+
+       u8 *sense;
+       dma_addr_t sense_phys_addr;
+
+       struct list_head list;
+       struct scsi_cmnd *scmd;
+       struct megasas_instance *instance;
+
+       u8 retry_for_fw_reset;
+       union MEGASAS_REQUEST_DESCRIPTOR_UNION  *request_desc;
+
+       /*
+        * Context for a MFI frame.
+        * Used to get the mfi cmd from list when a MFI cmd is completed
+        */
+       u32 sync_cmd_idx;
+       u32 index;
+       u8 flags;
+};
+
+struct LD_LOAD_BALANCE_INFO {
+       u8      loadBalanceFlag;
+       u8      reserved1;
+       u16     raid1DevHandle[2];
+       atomic_t     scsi_pending_cmds[2];
+       u64     last_accessed_block[2];
+};
+
+struct MR_FW_RAID_MAP_ALL {
+       struct MR_FW_RAID_MAP raidMap;
+       struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1];
+} __attribute__ ((packed));
+
+struct fusion_context {
+       struct megasas_cmd_fusion **cmd_list;
+       struct list_head cmd_pool;
+
+       spinlock_t cmd_pool_lock;
+
+       dma_addr_t req_frames_desc_phys;
+       u8 *req_frames_desc;
+
+       struct dma_pool *io_request_frames_pool;
+       dma_addr_t io_request_frames_phys;
+       u8 *io_request_frames;
+
+       struct dma_pool *sg_dma_pool;
+       struct dma_pool *sense_dma_pool;
+
+       dma_addr_t reply_frames_desc_phys;
+       union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc;
+       struct dma_pool *reply_frames_desc_pool;
+
+       u16 last_reply_idx;
+
+       u32 reply_q_depth;
+       u32 request_alloc_sz;
+       u32 reply_alloc_sz;
+       u32 io_frames_alloc_sz;
+
+       u16     max_sge_in_main_msg;
+       u16     max_sge_in_chain;
+
+       u8      chain_offset_io_request;
+       u8      chain_offset_mfi_pthru;
+
+       struct MR_FW_RAID_MAP_ALL *ld_map[2];
+       dma_addr_t ld_map_phys[2];
+
+       u32 map_sz;
+       u8 fast_path_io;
+       struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES];
+};
+
+union desc_value {
+       u64 word;
+       struct {
+               u32 low;
+               u32 high;
+       } u;
+};
+
+#endif /* _MEGARAID_SAS_FUSION_H_ */
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 4b1c2f0350f9cb75821344987295875a03c47781..8be75e65f76301a95fe6f7f77a4ad82c4cc92ce3 100644 (file)
@@ -8,7 +8,7 @@
  *                  scatter/gather formats.
  *  Creation Date:  June 21, 2006
  *
- *  mpi2.h Version:  02.00.15
+ *  mpi2.h Version:  02.00.16
  *
  *  Version History
  *  ---------------
@@ -61,6 +61,8 @@
  *                      Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL.
  *                      Added defines for product-specific range of message
  *                      function codes, 0xF0 to 0xFF.
+ *  05-12-10  02.00.16  Bumped MPI2_HEADER_VERSION_UNIT.
+ *                      Added alternative defines for the SGE Direction bit.
  *  --------------------------------------------------------------------------
  */
 
@@ -86,7 +88,7 @@
 #define MPI2_VERSION_02_00                  (0x0200)
 
 /* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x0F)
+#define MPI2_HEADER_VERSION_UNIT            (0x10)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
@@ -929,6 +931,9 @@ typedef struct _MPI2_MPI_SGE_UNION
 #define MPI2_SGE_FLAGS_IOC_TO_HOST              (0x00)
 #define MPI2_SGE_FLAGS_HOST_TO_IOC              (0x04)
 
+#define MPI2_SGE_FLAGS_DEST                     (MPI2_SGE_FLAGS_IOC_TO_HOST)
+#define MPI2_SGE_FLAGS_SOURCE                   (MPI2_SGE_FLAGS_HOST_TO_IOC)
+
 /* Address Size */
 
 #define MPI2_SGE_FLAGS_32_BIT_ADDRESSING        (0x00)
index e3728d736d851d9731768ae1c119061b0a77b75d..d76a658476039b76ee0e31bf090c70a47197b68c 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI Configuration messages and pages
  *  Creation Date:  November 10, 2006
  *
- *    mpi2_cnfg.h Version:  02.00.14
+ *    mpi2_cnfg.h Version:  02.00.15
  *
  *  Version History
  *  ---------------
  *                      Added MPI2_CONFIG_PAGE_SASIOUNIT_6 and related defines.
  *                      Added MPI2_CONFIG_PAGE_SASIOUNIT_7 and related defines.
  *                      Added MPI2_CONFIG_PAGE_SASIOUNIT_8 and related defines.
+ *  05-12-10  02.00.15  Added MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT
+ *                      define.
+ *                      Added MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE define.
+ *                      Added MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY define.
  *  --------------------------------------------------------------------------
  */
 
@@ -333,7 +337,7 @@ typedef struct _MPI2_CONFIG_REQUEST
 #define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM          (0x06)
 #define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE      (0x07)
 
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
 
 
 /* Config Reply Message */
@@ -379,6 +383,8 @@ typedef struct _MPI2_CONFIG_REPLY
 #define MPI2_MFGPAGE_DEVID_SAS2116_1                (0x0064)
 #define MPI2_MFGPAGE_DEVID_SAS2116_2                (0x0065)
 
+#define MPI2_MFGPAGE_DEVID_SSS6200                  (0x007E)
+
 #define MPI2_MFGPAGE_DEVID_SAS2208_1                (0x0080)
 #define MPI2_MFGPAGE_DEVID_SAS2208_2                (0x0081)
 #define MPI2_MFGPAGE_DEVID_SAS2208_3                (0x0082)
@@ -390,6 +396,8 @@ typedef struct _MPI2_CONFIG_REPLY
 #define MPI2_MFGPAGE_DEVID_SAS2308_3                (0x006E)
 
 
+
+
 /* Manufacturing Page 0 */
 
 typedef struct _MPI2_CONFIG_PAGE_MAN_0
@@ -729,6 +737,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1
 /* IO Unit Page 1 Flags defines */
 #define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY    (0x00000800)
 #define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE          (0x00000600)
+#define MPI2_IOUNITPAGE1_SATA_WRITE_CACHE_SHIFT         (9)
 #define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE        (0x00000000)
 #define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE       (0x00000200)
 #define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE     (0x00000400)
@@ -1347,6 +1356,7 @@ typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_0
 #define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION        (0x00040000)
 #define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT           (0x00020000)
 #define MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS        (0x00010000)
+#define MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT        (0x00000080)
 #define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED               (0x00000040)
 #define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE              (0x00000020)
 #define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR          (0x00000000)
@@ -1469,11 +1479,15 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0
 #define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA             (0x03)
 #define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD   (0x04)
 #define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA    (0x05)
+#define MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE          (0x06)
 #define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN             (0xFF)
 
 /* PhysDiskAttributes defines */
+#define MPI2_PHYSDISK0_ATTRIB_MEDIA_MASK                (0x0C)
 #define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE         (0x08)
 #define MPI2_PHYSDISK0_ATTRIB_HARD_DISK_DRIVE           (0x04)
+
+#define MPI2_PHYSDISK0_ATTRIB_PROTOCOL_MASK             (0x03)
 #define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL              (0x02)
 #define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL             (0x01)
 
@@ -1545,6 +1559,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
 #define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE        (0x03)
 #define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR            (0x04)
 #define MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS    (0x05)
+#define MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY          (0x06)
 #define MPI2_SAS_NEG_LINK_RATE_1_5                      (0x08)
 #define MPI2_SAS_NEG_LINK_RATE_3_0                      (0x09)
 #define MPI2_SAS_NEG_LINK_RATE_6_0                      (0x0A)
@@ -1571,6 +1586,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
 #define MPI2_SAS_PHYINFO_PHY_VACANT                     (0x80000000)
 
 #define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK       (0x18000000)
+#define MPI2_SAS_PHYINFO_SHIFT_PHY_POWER_CONDITION      (27)
 #define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE               (0x00000000)
 #define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL              (0x08000000)
 #define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER              (0x10000000)
index bd6c92b5fae56e971df823e805fc8aff5ce6d5d5..b1e88f26b748b6e935516bdb6a631087ca119606 100644 (file)
@@ -291,6 +291,7 @@ mpi2_raid.h
  *                      can be sized by the build environment.
  *  07-30-09  02.00.04  Added proper define for the Use Default Settings bit of
  *                      VolumeCreationFlags and marked the old one as obsolete.
+ *  05-12-10  02.00.05  Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
  *  --------------------------------------------------------------------------
 
 mpi2_sas.h
@@ -301,6 +302,7 @@ mpi2_sas.h
  *                      Request.
  *  10-28-09  02.00.03  Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
  *                      to MPI2_SGE_IO_UNION since it supports chained SGLs.
+ *  05-12-10  02.00.04  Modified some comments.
  *  --------------------------------------------------------------------------
 
 mpi2_targ.h
@@ -324,6 +326,7 @@ mpi2_tool.h
  *                      and reply messages.
  *                      Added MPI2_DIAG_BUF_TYPE_EXTENDED.
  *                      Incremented MPI2_DIAG_BUF_TYPE_COUNT.
+ *  05-12-10  02.00.05  Added Diagnostic Data Upload tool.
  *  --------------------------------------------------------------------------
 
 mpi2_type.h
index c4c99dfcb82024f0979fa49adb078386caa31786..20e6b88693411835c755f91b1be046eda0b2cc0a 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI SCSI initiator mode messages and structures
  *  Creation Date:  June 23, 2006
  *
- *    mpi2_init.h Version:  02.00.09
+ *    mpi2_init.h Version:  02.00.10
  *
  *  Version History
  *  ---------------
@@ -32,6 +32,7 @@
  *                      Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY.
  *                      Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define.
  *  02-10-10  02.00.09  Removed unused structure that had "#if 0" around it.
+ *  05-12-10  02.00.10  Added optional vendor-unique region to SCSI IO Request.
  *  --------------------------------------------------------------------------
  */
 
@@ -98,7 +99,13 @@ typedef struct _MPI2_SCSI_IO_REQUEST
     U8                      LUN[8];                         /* 0x34 */
     U32                     Control;                        /* 0x3C */
     MPI2_SCSI_IO_CDB_UNION  CDB;                            /* 0x40 */
+
+#ifdef MPI2_SCSI_IO_VENDOR_UNIQUE_REGION /* typically this is left undefined */
+       MPI2_SCSI_IO_VENDOR_UNIQUE VendorRegion;
+#endif
+
     MPI2_SGE_IO_UNION       SGL;                            /* 0x60 */
+
 } MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST,
   Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t;
 
index 495bedc4d1f7bb48b5430aec941a049de595bac2..761cbdb8a033164ab0b3230bf23294ab5e36a436 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  October 11, 2006
  *
- *  mpi2_ioc.h Version:  02.00.14
+ *  mpi2_ioc.h Version:  02.00.15
  *
  *  Version History
  *  ---------------
  *  02-10-10  02.00.14  Added SAS Quiesce Event structure and defines.
  *                      Added PowerManagementControl Request structures and
  *                      defines.
+ *  05-12-10  02.00.15  Marked Task Set Full Event as obsolete.
+ *                      Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define.
  *  --------------------------------------------------------------------------
  */
 
@@ -456,7 +458,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
 #define MPI2_EVENT_STATE_CHANGE                     (0x0002)
 #define MPI2_EVENT_HARD_RESET_RECEIVED              (0x0005)
 #define MPI2_EVENT_EVENT_CHANGE                     (0x000A)
-#define MPI2_EVENT_TASK_SET_FULL                    (0x000E)
+#define MPI2_EVENT_TASK_SET_FULL                    (0x000E) /* obsolete */
 #define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE         (0x000F)
 #define MPI2_EVENT_IR_OPERATION_STATUS              (0x0014)
 #define MPI2_EVENT_SAS_DISCOVERY                    (0x0016)
@@ -517,6 +519,7 @@ typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
   MPI2_POINTER pMpi2EventDataHardResetReceived_t;
 
 /* Task Set Full Event data */
+/*   this event is obsolete */
 
 typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL
 {
@@ -831,6 +834,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST
 #define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE            (0x03)
 #define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR                (0x04)
 #define MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS        (0x05)
+#define MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY              (0x06)
 #define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5                     (0x08)
 #define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0                     (0x09)
 #define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0                     (0x0A)
index 5160c33d2a00b72a4687bad5d337f53c2da2e3f1..bd61a7b60a2bcf2c306517a0b1a45913b156c258 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2008 LSI Corporation.
+ *  Copyright (c) 2000-2010 LSI Corporation.
  *
  *
  *           Name:  mpi2_raid.h
  *          Title:  MPI Integrated RAID messages and structures
  *  Creation Date:  April 26, 2007
  *
- *    mpi2_raid.h Version:  02.00.04
+ *    mpi2_raid.h Version:  02.00.05
  *
  *  Version History
  *  ---------------
@@ -22,6 +22,7 @@
  *                      can be sized by the build environment.
  *  07-30-09  02.00.04  Added proper define for the Use Default Settings bit of
  *                      VolumeCreationFlags and marked the old one as obsolete.
+ *  05-12-10  02.00.05  Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
  *  --------------------------------------------------------------------------
  */
 
@@ -260,6 +261,7 @@ typedef struct _MPI2_RAID_VOL_INDICATOR
 #define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
 #define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK    (0x00000002)
 #define MPI2_RAID_VOL_FLAGS_OP_RESYNC               (0x00000003)
+#define MPI2_RAID_VOL_FLAGS_OP_MDC                  (0x00000004)
 
 
 /* RAID Action Reply ActionData union */
index 2d8aeed51392c566d2a1b4edfa14f847643662c0..608f6d6e6fcae8b242e5a2856f6c8c98185b676e 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2007 LSI Corporation.
+ *  Copyright (c) 2000-2010 LSI Corporation.
  *
  *
  *           Name:  mpi2_sas.h
  *          Title:  MPI Serial Attached SCSI structures and definitions
  *  Creation Date:  February 9, 2007
  *
- *  mpi2.h Version:  02.00.03
+ *  mpi2_sas.h Version:  02.00.04
  *
  *  Version History
  *  ---------------
@@ -20,6 +20,7 @@
  *                      Request.
  *  10-28-09  02.00.03  Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
  *                      to MPI2_SGE_IO_UNION since it supports chained SGLs.
+ *  05-12-10  02.00.04  Modified some comments.
  *  --------------------------------------------------------------------------
  */
 
@@ -110,7 +111,7 @@ typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST
 /* values for PassthroughFlags field */
 #define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE      (0x80)
 
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
 
 
 /* SMP Passthrough Reply Message */
@@ -174,7 +175,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST
 #define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE             (0x0002)
 #define MPI2_SATA_PT_REQ_PT_FLAGS_READ              (0x0001)
 
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
 
 
 /* SATA Passthrough Reply Message */
index 686b09b812197438821255c86ff8fadda7c81ef5..5c6e3a67bb9431ba98f396ffabec96a475e3e196 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI diagnostic tool structures and definitions
  *  Creation Date:  March 26, 2007
  *
- *    mpi2_tool.h Version:  02.00.04
+ *    mpi2_tool.h Version:  02.00.05
  *
  *  Version History
  *  ---------------
@@ -22,6 +22,7 @@
  *                      and reply messages.
  *                      Added MPI2_DIAG_BUF_TYPE_EXTENDED.
  *                      Incremented MPI2_DIAG_BUF_TYPE_COUNT.
+ *  05-12-10  02.00.05  Added Diagnostic Data Upload tool.
  *  --------------------------------------------------------------------------
  */
 
@@ -37,6 +38,7 @@
 /* defines for the Tools */
 #define MPI2_TOOLBOX_CLEAN_TOOL                     (0x00)
 #define MPI2_TOOLBOX_MEMORY_MOVE_TOOL               (0x01)
+#define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL          (0x02)
 #define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL          (0x03)
 #define MPI2_TOOLBOX_BEACON_TOOL                    (0x05)
 #define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL            (0x06)
@@ -102,8 +104,7 @@ typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST
 *  Toolbox Memory Move request
 ****************************************************************************/
 
-typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST
-{
+typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST {
     U8                      Tool;                       /* 0x00 */
     U8                      Reserved1;                  /* 0x01 */
     U8                      ChainOffset;                /* 0x02 */
@@ -119,6 +120,44 @@ typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST
   Mpi2ToolboxMemMoveRequest_t, MPI2_POINTER pMpi2ToolboxMemMoveRequest_t;
 
 
+/****************************************************************************
+*  Toolbox Diagnostic Data Upload request
+****************************************************************************/
+
+typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST {
+       U8                      Tool;                       /* 0x00 */
+       U8                      Reserved1;                  /* 0x01 */
+       U8                      ChainOffset;                /* 0x02 */
+       U8                      Function;                   /* 0x03 */
+       U16                     Reserved2;                  /* 0x04 */
+       U8                      Reserved3;                  /* 0x06 */
+       U8                      MsgFlags;                   /* 0x07 */
+       U8                      VP_ID;                      /* 0x08 */
+       U8                      VF_ID;                      /* 0x09 */
+       U16                     Reserved4;                  /* 0x0A */
+       U8                      SGLFlags;                   /* 0x0C */
+       U8                      Reserved5;                  /* 0x0D */
+       U16                     Reserved6;                  /* 0x0E */
+       U32                     Flags;                      /* 0x10 */
+       U32                     DataLength;                 /* 0x14 */
+       MPI2_SGE_SIMPLE_UNION   SGL;                        /* 0x18 */
+} MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
+MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
+Mpi2ToolboxDiagDataUploadRequest_t,
+MPI2_POINTER pMpi2ToolboxDiagDataUploadRequest_t;
+
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
+
+
+typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER {
+       U32                     DiagDataLength;             /* 00h */
+       U8                      FormatCode;                 /* 04h */
+       U8                      Reserved1;                  /* 05h */
+       U16                     Reserved2;                  /* 06h */
+} MPI2_DIAG_DATA_UPLOAD_HEADER, MPI2_POINTER PTR_MPI2_DIAG_DATA_UPLOAD_HEADER,
+Mpi2DiagDataUploadHeader_t, MPI2_POINTER pMpi2DiagDataUploadHeader_t;
+
+
 /****************************************************************************
 *  Toolbox ISTWI Read Write Tool
 ****************************************************************************/
@@ -162,7 +201,7 @@ typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST {
 #define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS          (0x11)
 #define MPI2_TOOL_ISTWI_ACTION_RESET                (0x12)
 
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
 
 
 /* Toolbox ISTWI Read Write Tool reply message */
@@ -248,7 +287,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
   Mpi2ToolboxDiagnosticCliRequest_t,
   MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t;
 
-/* values for SGLFlags field are in the SGL section of mpi2.h */
+/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
 
 
 /* Toolbox Diagnostic CLI Tool reply message */
index 12faf64f91b0cf937b0f62768d1093a70d79b29c..b2a817055b8b40c8868df1fd2e5a1708b91da023 100644 (file)
@@ -65,7 +65,6 @@
 static MPT_CALLBACK    mpt_callbacks[MPT_MAX_CALLBACKS];
 
 #define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
-#define MPT2SAS_MAX_REQUEST_QUEUE 600 /* maximum controller queue depth */
 
 static int max_queue_depth = -1;
 module_param(max_queue_depth, int, 0);
@@ -79,6 +78,10 @@ static int msix_disable = -1;
 module_param(msix_disable, int, 0);
 MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
 
+static int missing_delay[2] = {-1, -1};
+module_param_array(missing_delay, int, NULL, 0);
+MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
+
 /* diag_buffer_enable is bitwise
  * bit 0 set = TRACE
  * bit 1 set = SNAPSHOT
@@ -515,9 +518,6 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
        case MPI2_EVENT_EVENT_CHANGE:
                desc = "Event Change";
                break;
-       case MPI2_EVENT_TASK_SET_FULL:
-               desc = "Task Set Full";
-               break;
        case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
                desc = "Device Status Change";
                break;
@@ -758,7 +758,7 @@ _base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid)
                if (smid < ioc->internal_smid) {
                        i = smid - ioc->hi_priority_smid;
                        cb_idx = ioc->hpr_lookup[i].cb_idx;
-               } else {
+               } else if (smid <= ioc->hba_queue_depth)  {
                        i = smid - ioc->internal_smid;
                        cb_idx = ioc->internal_lookup[i].cb_idx;
                }
@@ -848,6 +848,7 @@ _base_interrupt(int irq, void *bus_id)
                return IRQ_NONE;
 
        completed_cmds = 0;
+       cb_idx = 0xFF;
        do {
                rd.word = rpf->Words;
                if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX)
@@ -860,6 +861,9 @@ _base_interrupt(int irq, void *bus_id)
                    MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
                        reply = le32_to_cpu
                                (rpf->AddressReply.ReplyFrameAddress);
+                       if (reply > ioc->reply_dma_max_address ||
+                           reply < ioc->reply_dma_min_address)
+                               reply = 0;
                } else if (request_desript_type ==
                    MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER)
                        goto next;
@@ -1489,6 +1493,7 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
 {
        unsigned long flags;
        int i;
+       struct chain_tracker *chain_req, *next;
 
        spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
        if (smid >= ioc->hi_priority_smid) {
@@ -1511,6 +1516,14 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
 
        /* scsiio queue */
        i = smid - 1;
+       if (!list_empty(&ioc->scsi_lookup[i].chain_list)) {
+               list_for_each_entry_safe(chain_req, next,
+                   &ioc->scsi_lookup[i].chain_list, tracker_list) {
+                       list_del_init(&chain_req->tracker_list);
+                       list_add_tail(&chain_req->tracker_list,
+                           &ioc->free_chain_list);
+               }
+       }
        ioc->scsi_lookup[i].cb_idx = 0xFF;
        ioc->scsi_lookup[i].scmd = NULL;
        list_add_tail(&ioc->scsi_lookup[i].tracker_list,
@@ -1818,6 +1831,97 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
        printk(")\n");
 }
 
+/**
+ * _base_update_missing_delay - change the missing delay timers
+ * @ioc: per adapter object
+ * @device_missing_delay: amount of time till device is reported missing
+ * @io_missing_delay: interval IO is returned when there is a missing device
+ *
+ * Return nothing.
+ *
+ * Passed on the command line, this function will modify the device missing
+ * delay, as well as the io missing delay. This should be called at driver
+ * load time.
+ */
+static void
+_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
+       u16 device_missing_delay, u8 io_missing_delay)
+{
+       u16 dmd, dmd_new, dmd_orignal;
+       u8 io_missing_delay_original;
+       u16 sz;
+       Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
+       Mpi2ConfigReply_t mpi_reply;
+       u8 num_phys = 0;
+       u16 ioc_status;
+
+       mpt2sas_config_get_number_hba_phys(ioc, &num_phys);
+       if (!num_phys)
+               return;
+
+       sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (num_phys *
+           sizeof(Mpi2SasIOUnit1PhyData_t));
+       sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
+       if (!sas_iounit_pg1) {
+               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                   ioc->name, __FILE__, __LINE__, __func__);
+               goto out;
+       }
+       if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
+           sas_iounit_pg1, sz))) {
+               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                   ioc->name, __FILE__, __LINE__, __func__);
+               goto out;
+       }
+       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+           MPI2_IOCSTATUS_MASK;
+       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                   ioc->name, __FILE__, __LINE__, __func__);
+               goto out;
+       }
+
+       /* device missing delay */
+       dmd = sas_iounit_pg1->ReportDeviceMissingDelay;
+       if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
+               dmd = (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
+       else
+               dmd = dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
+       dmd_orignal = dmd;
+       if (device_missing_delay > 0x7F) {
+               dmd = (device_missing_delay > 0x7F0) ? 0x7F0 :
+                   device_missing_delay;
+               dmd = dmd / 16;
+               dmd |= MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16;
+       } else
+               dmd = device_missing_delay;
+       sas_iounit_pg1->ReportDeviceMissingDelay = dmd;
+
+       /* io missing delay */
+       io_missing_delay_original = sas_iounit_pg1->IODeviceMissingDelay;
+       sas_iounit_pg1->IODeviceMissingDelay = io_missing_delay;
+
+       if (!mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
+           sz)) {
+               if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
+                       dmd_new = (dmd &
+                           MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
+               else
+                       dmd_new =
+                   dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
+               printk(MPT2SAS_INFO_FMT "device_missing_delay: old(%d), "
+                   "new(%d)\n", ioc->name, dmd_orignal, dmd_new);
+               printk(MPT2SAS_INFO_FMT "ioc_missing_delay: old(%d), "
+                   "new(%d)\n", ioc->name, io_missing_delay_original,
+                   io_missing_delay);
+               ioc->device_missing_delay = dmd_new;
+               ioc->io_missing_delay = io_missing_delay;
+       }
+
+out:
+       kfree(sas_iounit_pg1);
+}
+
 /**
  * _base_static_config_pages - static start of day config pages
  * @ioc: per adapter object
@@ -1855,6 +1959,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
                    MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
        ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags);
        mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1);
+
 }
 
 /**
@@ -1868,6 +1973,8 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
 static void
 _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
 {
+       int i;
+
        dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
            __func__));
 
@@ -1932,6 +2039,20 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
        }
        kfree(ioc->hpr_lookup);
        kfree(ioc->internal_lookup);
+       if (ioc->chain_lookup) {
+               for (i = 0; i < ioc->chain_depth; i++) {
+                       if (ioc->chain_lookup[i].chain_buffer)
+                               pci_pool_free(ioc->chain_dma_pool,
+                                   ioc->chain_lookup[i].chain_buffer,
+                                   ioc->chain_lookup[i].chain_buffer_dma);
+               }
+               if (ioc->chain_dma_pool)
+                       pci_pool_destroy(ioc->chain_dma_pool);
+       }
+       if (ioc->chain_lookup) {
+               free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
+               ioc->chain_lookup = NULL;
+       }
 }
 
 
@@ -1953,6 +2074,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
        u32 sz, total_sz;
        u32 retry_sz;
        u16 max_request_credit;
+       int i;
 
        dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
            __func__));
@@ -1970,14 +2092,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
        }
 
        /* command line tunables  for max controller queue depth */
-       if (max_queue_depth != -1) {
+       if (max_queue_depth != -1)
                max_request_credit = (max_queue_depth < facts->RequestCredit)
                    ? max_queue_depth : facts->RequestCredit;
-       } else {
-               max_request_credit = (facts->RequestCredit >
-                   MPT2SAS_MAX_REQUEST_QUEUE) ? MPT2SAS_MAX_REQUEST_QUEUE :
-                   facts->RequestCredit;
-       }
+       else
+               max_request_credit = facts->RequestCredit;
 
        ioc->hba_queue_depth = max_request_credit;
        ioc->hi_priority_depth = facts->HighPriorityCredit;
@@ -2083,7 +2202,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
         * "frame for smid=0
         */
        ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth;
-       sz = ((ioc->scsiio_depth + 1 + ioc->chain_depth) * ioc->request_sz);
+       sz = ((ioc->scsiio_depth + 1) * ioc->request_sz);
 
        /* hi-priority queue */
        sz += (ioc->hi_priority_depth * ioc->request_sz);
@@ -2124,19 +2243,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
        ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth *
            ioc->request_sz);
 
-       ioc->chain = ioc->internal + (ioc->internal_depth *
-           ioc->request_sz);
-       ioc->chain_dma = ioc->internal_dma + (ioc->internal_depth *
-           ioc->request_sz);
 
        dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): "
            "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
            ioc->request, ioc->hba_queue_depth, ioc->request_sz,
            (ioc->hba_queue_depth * ioc->request_sz)/1024));
-       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool(0x%p): depth"
-           "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->chain,
-           ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
-           ioc->request_sz))/1024));
        dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n",
            ioc->name, (unsigned long long) ioc->request_dma));
        total_sz += sz;
@@ -2155,6 +2266,38 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
            "depth(%d)\n", ioc->name, ioc->request,
            ioc->scsiio_depth));
 
+       /* loop till the allocation succeeds */
+       do {
+               sz = ioc->chain_depth * sizeof(struct chain_tracker);
+               ioc->chain_pages = get_order(sz);
+               ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
+                   GFP_KERNEL, ioc->chain_pages);
+               if (ioc->chain_lookup == NULL)
+                       ioc->chain_depth -= 100;
+       } while (ioc->chain_lookup == NULL);
+       ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
+           ioc->request_sz, 16, 0);
+       if (!ioc->chain_dma_pool) {
+               printk(MPT2SAS_ERR_FMT "chain_dma_pool: pci_pool_create "
+                   "failed\n", ioc->name);
+               goto out;
+       }
+       for (i = 0; i < ioc->chain_depth; i++) {
+               ioc->chain_lookup[i].chain_buffer = pci_pool_alloc(
+                   ioc->chain_dma_pool , GFP_KERNEL,
+                   &ioc->chain_lookup[i].chain_buffer_dma);
+               if (!ioc->chain_lookup[i].chain_buffer) {
+                       ioc->chain_depth = i;
+                       goto chain_done;
+               }
+               total_sz += ioc->request_sz;
+       }
+chain_done:
+       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool depth"
+           "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
+           ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
+           ioc->request_sz))/1024));
+
        /* initialize hi-priority queue smid's */
        ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
            sizeof(struct request_tracker), GFP_KERNEL);
@@ -2221,6 +2364,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
                    ioc->name);
                goto out;
        }
+       ioc->reply_dma_min_address = (u32)(ioc->reply_dma);
+       ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz;
        dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply pool(0x%p): depth"
            "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->reply,
            ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024));
@@ -2302,7 +2447,6 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
        return 0;
 
  out:
-       _base_release_memory_pools(ioc);
        return -ENOMEM;
 }
 
@@ -3485,6 +3629,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
        INIT_LIST_HEAD(&ioc->free_list);
        smid = 1;
        for (i = 0; i < ioc->scsiio_depth; i++, smid++) {
+               INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list);
                ioc->scsi_lookup[i].cb_idx = 0xFF;
                ioc->scsi_lookup[i].smid = smid;
                ioc->scsi_lookup[i].scmd = NULL;
@@ -3511,6 +3656,13 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
                list_add_tail(&ioc->internal_lookup[i].tracker_list,
                    &ioc->internal_free_list);
        }
+
+       /* chain pool */
+       INIT_LIST_HEAD(&ioc->free_chain_list);
+       for (i = 0; i < ioc->chain_depth; i++)
+               list_add_tail(&ioc->chain_lookup[i].tracker_list,
+                   &ioc->free_chain_list);
+
        spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
 
        /* initialize Reply Free Queue */
@@ -3708,12 +3860,15 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
        _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME);
        _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK);
        _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
-       _base_unmask_events(ioc, MPI2_EVENT_TASK_SET_FULL);
        _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
        r = _base_make_ioc_operational(ioc, CAN_SLEEP);
        if (r)
                goto out_free_resources;
 
+       if (missing_delay[0] != -1 && missing_delay[1] != -1)
+               _base_update_missing_delay(ioc, missing_delay[0],
+                   missing_delay[1]);
+
        mpt2sas_base_start_watchdog(ioc);
        return 0;
 
index 0b15a8bdebfc4a62f7bd119b2fca641c9d48cac8..283568c6fb049728c432774185a6b2f70000e37f 100644 (file)
@@ -69,8 +69,8 @@
 #define MPT2SAS_DRIVER_NAME            "mpt2sas"
 #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
 #define MPT2SAS_DESCRIPTION    "LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION         "06.100.00.00"
-#define MPT2SAS_MAJOR_VERSION          06
+#define MPT2SAS_DRIVER_VERSION         "07.100.00.00"
+#define MPT2SAS_MAJOR_VERSION          07
 #define MPT2SAS_MINOR_VERSION          100
 #define MPT2SAS_BUILD_VERSION          00
 #define MPT2SAS_RELEASE_VERSION                00
@@ -418,6 +418,18 @@ enum reset_type {
        SOFT_RESET,
 };
 
+/**
+ * struct chain_tracker - firmware chain tracker
+ * @chain_buffer: chain buffer
+ * @chain_buffer_dma: physical address
+ * @tracker_list: list of free request (ioc->free_chain_list)
+ */
+struct chain_tracker {
+       void *chain_buffer;
+       dma_addr_t chain_buffer_dma;
+       struct list_head tracker_list;
+};
+
 /**
  * struct request_tracker - firmware request tracker
  * @smid: system message id
@@ -430,6 +442,7 @@ struct request_tracker {
        u16     smid;
        struct scsi_cmnd *scmd;
        u8      cb_idx;
+       struct list_head chain_list;
        struct list_head tracker_list;
 };
 
@@ -704,8 +717,10 @@ struct MPT2SAS_ADAPTER {
        wait_queue_head_t reset_wq;
 
        /* chain */
-       u8              *chain;
-       dma_addr_t      chain_dma;
+       struct chain_tracker *chain_lookup;
+       struct list_head free_chain_list;
+       struct dma_pool *chain_dma_pool;
+       ulong           chain_pages;
        u16             max_sges_in_main_message;
        u16             max_sges_in_chain_message;
        u16             chains_needed_per_io;
@@ -737,6 +752,8 @@ struct MPT2SAS_ADAPTER {
        u16             reply_sz;
        u8              *reply;
        dma_addr_t      reply_dma;
+       u32             reply_dma_max_address;
+       u32             reply_dma_min_address;
        struct dma_pool *reply_dma_pool;
 
        /* reply free queue */
@@ -832,6 +849,8 @@ int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
     ulong timeout, struct scsi_cmnd *scmd);
 void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
 void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
+void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
+void mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
 struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc,
     u16 handle);
 struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER
index 40cb8aeb21b104303246667ab137d0d4670cada5..e92b77af5484919f2bde2d692557151b8e55f7f6 100644 (file)
@@ -81,6 +81,7 @@ enum block_state {
        BLOCKING,
 };
 
+#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
  * _ctl_sas_device_find_by_handle - sas device search
  * @ioc: per adapter object
@@ -107,7 +108,6 @@ _ctl_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
        return r;
 }
 
-#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
  * _ctl_display_some_debug - debug routine
  * @ioc: per adapter object
index 16e99b6863549ed0495cc283c884d9a162d34c01..eda347c5797928a8f3677592efc6f6aba9b5ab27 100644 (file)
@@ -931,31 +931,32 @@ _scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id,
 }
 
 /**
- * _scsih_get_chain_buffer_dma - obtain block of chains (dma address)
+ * _scsih_get_chain_buffer_tracker - obtain chain tracker
  * @ioc: per adapter object
- * @smid: system request message index
+ * @smid: smid associated to an IO request
  *
- * Returns phys pointer to chain buffer.
+ * Returns chain tracker(from ioc->free_chain_list)
  */
-static dma_addr_t
-_scsih_get_chain_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
+static struct chain_tracker *
+_scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid)
 {
-       return ioc->chain_dma + ((smid - 1) * (ioc->request_sz *
-           ioc->chains_needed_per_io));
-}
+       struct chain_tracker *chain_req;
+       unsigned long flags;
 
-/**
- * _scsih_get_chain_buffer - obtain block of chains assigned to a mf request
- * @ioc: per adapter object
- * @smid: system request message index
- *
- * Returns virt pointer to chain buffer.
- */
-static void *
-_scsih_get_chain_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid)
-{
-       return (void *)(ioc->chain + ((smid - 1) * (ioc->request_sz *
-           ioc->chains_needed_per_io)));
+       spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
+       if (list_empty(&ioc->free_chain_list)) {
+               spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+               printk(MPT2SAS_WARN_FMT "chain buffers not available\n",
+                   ioc->name);
+               return NULL;
+       }
+       chain_req = list_entry(ioc->free_chain_list.next,
+           struct chain_tracker, tracker_list);
+       list_del_init(&chain_req->tracker_list);
+       list_add_tail(&chain_req->tracker_list,
+           &ioc->scsi_lookup[smid - 1].chain_list);
+       spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+       return chain_req;
 }
 
 /**
@@ -986,6 +987,7 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
        u32 sgl_flags;
        u32 sgl_flags_last_element;
        u32 sgl_flags_end_buffer;
+       struct chain_tracker *chain_req;
 
        mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
 
@@ -1033,8 +1035,11 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
 
        /* initializing the chain flags and pointers */
        chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT;
-       chain = _scsih_get_chain_buffer(ioc, smid);
-       chain_dma = _scsih_get_chain_buffer_dma(ioc, smid);
+       chain_req = _scsih_get_chain_buffer_tracker(ioc, smid);
+       if (!chain_req)
+               return -1;
+       chain = chain_req->chain_buffer;
+       chain_dma = chain_req->chain_buffer_dma;
        do {
                sges_in_segment = (sges_left <=
                    ioc->max_sges_in_chain_message) ? sges_left :
@@ -1070,8 +1075,11 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
                        sges_in_segment--;
                }
 
-               chain_dma += ioc->request_sz;
-               chain += ioc->request_sz;
+               chain_req = _scsih_get_chain_buffer_tracker(ioc, smid);
+               if (!chain_req)
+                       return -1;
+               chain = chain_req->chain_buffer;
+               chain_dma = chain_req->chain_buffer_dma;
        } while (1);
 
 
@@ -1094,28 +1102,24 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
 }
 
 /**
- * _scsih_change_queue_depth - setting device queue depth
+ * _scsih_adjust_queue_depth - setting device queue depth
  * @sdev: scsi device struct
  * @qdepth: requested queue depth
- * @reason: calling context
  *
- * Returns queue depth.
+ *
+ * Returns nothing
  */
-static int
-_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
+static void
+_scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth)
 {
        struct Scsi_Host *shost = sdev->host;
        int max_depth;
-       int tag_type;
        struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
        struct MPT2SAS_DEVICE *sas_device_priv_data;
        struct MPT2SAS_TARGET *sas_target_priv_data;
        struct _sas_device *sas_device;
        unsigned long flags;
 
-       if (reason != SCSI_QDEPTH_DEFAULT)
-               return -EOPNOTSUPP;
-
        max_depth = shost->can_queue;
 
        /* limit max device queue for SATA to 32 */
@@ -1141,8 +1145,27 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
                max_depth = 1;
        if (qdepth > max_depth)
                qdepth = max_depth;
-       tag_type = (qdepth == 1) ? 0 : MSG_SIMPLE_TAG;
-       scsi_adjust_queue_depth(sdev, tag_type, qdepth);
+       scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+}
+
+/**
+ * _scsih_change_queue_depth - setting device queue depth
+ * @sdev: scsi device struct
+ * @qdepth: requested queue depth
+ * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP
+ * (see include/scsi/scsi_host.h for definition)
+ *
+ * Returns queue depth.
+ */
+static int
+_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
+{
+       if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP)
+               _scsih_adjust_queue_depth(sdev, qdepth);
+       else if (reason == SCSI_QDEPTH_QFULL)
+               scsi_track_queue_full(sdev, qdepth);
+       else
+               return -EOPNOTSUPP;
 
        if (sdev->inquiry_len > 7)
                sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), "
@@ -2251,13 +2274,13 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
 
        struct scsi_target *starget = scmd->device->sdev_target;
 
-       starget_printk(KERN_INFO, starget, "attempting target reset! "
+       starget_printk(KERN_INFO, starget, "attempting device reset! "
            "scmd(%p)\n", scmd);
        _scsih_tm_display_info(ioc, scmd);
 
        sas_device_priv_data = scmd->device->hostdata;
        if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
-               starget_printk(KERN_INFO, starget, "target been deleted! "
+               starget_printk(KERN_INFO, starget, "device been deleted! "
                    "scmd(%p)\n", scmd);
                scmd->result = DID_NO_CONNECT << 16;
                scmd->scsi_done(scmd);
@@ -2576,9 +2599,9 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc,
           &sas_expander->sas_port_list, port_list) {
 
                if (mpt2sas_port->remote_identify.device_type ==
-                   MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
+                   SAS_EDGE_EXPANDER_DEVICE ||
                    mpt2sas_port->remote_identify.device_type ==
-                   MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
+                   SAS_FANOUT_EXPANDER_DEVICE) {
 
                        spin_lock_irqsave(&ioc->sas_node_lock, flags);
                        expander_sibling =
@@ -2715,9 +2738,10 @@ static u8
 _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
     u8 msix_index, u32 reply)
 {
+#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
        Mpi2SasIoUnitControlReply_t *mpi_reply =
            mpt2sas_base_get_reply_virt_addr(ioc, reply);
-
+#endif
        dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
            "sc_complete:handle(0x%04x), (open) "
            "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -3315,7 +3339,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 +3465,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
@@ -3961,6 +3987,7 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
        Mpi2ConfigReply_t mpi_reply;
        Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
        u16 attached_handle;
+       u8 link_rate;
 
        dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
            "updating handles for sas_host(0x%016llx)\n",
@@ -3982,15 +4009,17 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
        if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
                goto out;
        for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
+               link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4;
                if (i == 0)
                        ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
                            PhyData[0].ControllerDevHandle);
                ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
                attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
                    AttachedDevHandle);
+               if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5)
+                       link_rate = MPI2_SAS_NEG_LINK_RATE_1_5;
                mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
-                   attached_handle, i, sas_iounit_pg0->PhyData[i].
-                   NegotiatedLinkRate >> 4);
+                   attached_handle, i, link_rate);
        }
  out:
        kfree(sas_iounit_pg0);
@@ -4334,14 +4363,14 @@ _scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
 }
 
 /**
- * _scsih_expander_remove - removing expander object
+ * mpt2sas_expander_remove - removing expander object
  * @ioc: per adapter object
  * @sas_address: expander sas_address
  *
  * Return nothing.
  */
-static void
-_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
+void
+mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
 {
        struct _sas_node *sas_expander;
        unsigned long flags;
@@ -4352,6 +4381,11 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
        spin_lock_irqsave(&ioc->sas_node_lock, flags);
        sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
            sas_address);
+       if (!sas_expander) {
+               spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
+               return;
+       }
+       list_del(&sas_expander->list);
        spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
        _scsih_expander_node_remove(ioc, sas_expander);
 }
@@ -4641,6 +4675,33 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
            sas_device_backup.sas_address));
 }
 
+/**
+ * mpt2sas_device_remove - removing device object
+ * @ioc: per adapter object
+ * @sas_address: expander sas_address
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
+{
+       struct _sas_device *sas_device;
+       unsigned long flags;
+
+       if (ioc->shost_recovery)
+               return;
+
+       spin_lock_irqsave(&ioc->sas_device_lock, flags);
+       sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+           sas_address);
+       if (!sas_device) {
+               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+               return;
+       }
+       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+       _scsih_remove_device(ioc, sas_device);
+}
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
  * _scsih_sas_topology_change_event_debug - debug for topology event
@@ -4735,7 +4796,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
        int i;
        u16 parent_handle, handle;
        u16 reason_code;
-       u8 phy_number;
+       u8 phy_number, max_phys;
        struct _sas_node *sas_expander;
        struct _sas_device *sas_device;
        u64 sas_address;
@@ -4773,11 +4834,13 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
        sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
            parent_handle);
        spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-       if (sas_expander)
+       if (sas_expander) {
                sas_address = sas_expander->sas_address;
-       else if (parent_handle < ioc->sas_hba.num_phys)
+               max_phys = sas_expander->num_phys;
+       } else if (parent_handle < ioc->sas_hba.num_phys) {
                sas_address = ioc->sas_hba.sas_address;
-       else
+               max_phys = ioc->sas_hba.num_phys;
+       } else
                return;
 
        /* handle siblings events */
@@ -4791,6 +4854,8 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
                    ioc->pci_error_recovery)
                        return;
                phy_number = event_data->StartPhyNum + i;
+               if (phy_number >= max_phys)
+                       continue;
                reason_code = event_data->PHY[i].PhyStatus &
                    MPI2_EVENT_SAS_TOPO_RC_MASK;
                if ((event_data->PHY[i].PhyStatus &
@@ -4842,7 +4907,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
        /* handle expander removal */
        if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
            sas_expander)
-               _scsih_expander_remove(ioc, sas_address);
+               mpt2sas_expander_remove(ioc, sas_address);
 
 }
 
@@ -5770,90 +5835,6 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
        }
 }
 
-/**
- * _scsih_task_set_full - handle task set full
- * @ioc: per adapter object
- * @fw_event: The fw_event_work object
- * Context: user.
- *
- * Throttle back qdepth.
- */
-static void
-_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
-       *fw_event)
-{
-       unsigned long flags;
-       struct _sas_device *sas_device;
-       static struct _raid_device *raid_device;
-       struct scsi_device *sdev;
-       int depth;
-       u16 current_depth;
-       u16 handle;
-       int id, channel;
-       u64 sas_address;
-       Mpi2EventDataTaskSetFull_t *event_data = fw_event->event_data;
-
-       current_depth = le16_to_cpu(event_data->CurrentDepth);
-       handle = le16_to_cpu(event_data->DevHandle);
-       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-       sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-       if (!sas_device) {
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-               return;
-       }
-       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       id = sas_device->id;
-       channel = sas_device->channel;
-       sas_address = sas_device->sas_address;
-
-       /* if hidden raid component, then change to volume characteristics */
-       if (test_bit(handle, ioc->pd_handles) && sas_device->volume_handle) {
-               spin_lock_irqsave(&ioc->raid_device_lock, flags);
-               raid_device = _scsih_raid_device_find_by_handle(
-                   ioc, sas_device->volume_handle);
-               spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
-               if (raid_device) {
-                       id = raid_device->id;
-                       channel = raid_device->channel;
-                       handle = raid_device->handle;
-                       sas_address = raid_device->wwid;
-               }
-       }
-
-       if (ioc->logging_level & MPT_DEBUG_TASK_SET_FULL)
-               starget_printk(KERN_INFO, sas_device->starget, "task set "
-                   "full: handle(0x%04x), sas_addr(0x%016llx), depth(%d)\n",
-                   handle, (unsigned long long)sas_address, current_depth);
-
-       shost_for_each_device(sdev, ioc->shost) {
-               if (sdev->id == id && sdev->channel == channel) {
-                       if (current_depth > sdev->queue_depth) {
-                               if (ioc->logging_level &
-                                   MPT_DEBUG_TASK_SET_FULL)
-                                       sdev_printk(KERN_INFO, sdev, "strange "
-                                           "observation, the queue depth is"
-                                           " (%d) meanwhile fw queue depth "
-                                           "is (%d)\n", sdev->queue_depth,
-                                           current_depth);
-                               continue;
-                       }
-                       depth = scsi_track_queue_full(sdev,
-                           current_depth - 1);
-                       if (depth > 0)
-                               sdev_printk(KERN_INFO, sdev, "Queue depth "
-                                   "reduced to (%d)\n", depth);
-                       else if (depth < 0)
-                               sdev_printk(KERN_INFO, sdev, "Tagged Command "
-                                   "Queueing is being disabled\n");
-                       else if (depth == 0)
-                               if (ioc->logging_level &
-                                    MPT_DEBUG_TASK_SET_FULL)
-                                       sdev_printk(KERN_INFO, sdev,
-                                            "Queue depth not changed yet\n");
-               }
-       }
-}
-
 /**
  * _scsih_prep_device_scan - initialize parameters prior to device scan
  * @ioc: per adapter object
@@ -6217,7 +6198,7 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
                        sas_expander->responding = 0;
                        continue;
                }
-               _scsih_expander_remove(ioc, sas_expander->sas_address);
+               mpt2sas_expander_remove(ioc, sas_expander->sas_address);
                goto retry_expander_search;
        }
 }
@@ -6341,9 +6322,6 @@ _firmware_event_work(struct work_struct *work)
        case MPI2_EVENT_IR_OPERATION_STATUS:
                _scsih_sas_ir_operation_status_event(ioc, fw_event);
                break;
-       case MPI2_EVENT_TASK_SET_FULL:
-               _scsih_task_set_full(ioc, fw_event);
-               break;
        }
        _scsih_fw_event_free(ioc, fw_event);
 }
@@ -6413,7 +6391,6 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
        case MPI2_EVENT_SAS_DISCOVERY:
        case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
        case MPI2_EVENT_IR_PHYSICAL_DISK:
-       case MPI2_EVENT_TASK_SET_FULL:
                break;
 
        default: /* ignore the rest */
@@ -6488,56 +6465,23 @@ static void
 _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
     struct _sas_node *sas_expander)
 {
-       struct _sas_port *mpt2sas_port;
-       struct _sas_device *sas_device;
-       struct _sas_node *expander_sibling;
-       unsigned long flags;
-
-       if (!sas_expander)
-               return;
+       struct _sas_port *mpt2sas_port, *next;
 
        /* remove sibling ports attached to this expander */
- retry_device_search:
-       list_for_each_entry(mpt2sas_port,
-          &sas_expander->sas_port_list, port_list) {
-               if (mpt2sas_port->remote_identify.device_type ==
-                   SAS_END_DEVICE) {
-                       spin_lock_irqsave(&ioc->sas_device_lock, flags);
-                       sas_device =
-                           mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
-                          mpt2sas_port->remote_identify.sas_address);
-                       spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-                       if (!sas_device)
-                               continue;
-                       _scsih_remove_device(ioc, sas_device);
-                       if (ioc->shost_recovery)
-                               return;
-                       goto retry_device_search;
-               }
-       }
-
- retry_expander_search:
-       list_for_each_entry(mpt2sas_port,
+       list_for_each_entry_safe(mpt2sas_port, next,
           &sas_expander->sas_port_list, port_list) {
-
+               if (ioc->shost_recovery)
+                       return;
                if (mpt2sas_port->remote_identify.device_type ==
-                   MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
+                   SAS_END_DEVICE)
+                       mpt2sas_device_remove(ioc,
+                           mpt2sas_port->remote_identify.sas_address);
+               else if (mpt2sas_port->remote_identify.device_type ==
+                   SAS_EDGE_EXPANDER_DEVICE ||
                    mpt2sas_port->remote_identify.device_type ==
-                   MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
-
-                       spin_lock_irqsave(&ioc->sas_node_lock, flags);
-                       expander_sibling =
-                           mpt2sas_scsih_expander_find_by_sas_address(
-                           ioc, mpt2sas_port->remote_identify.sas_address);
-                       spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
-                       if (!expander_sibling)
-                               continue;
-                       _scsih_expander_remove(ioc,
-                           expander_sibling->sas_address);
-                       if (ioc->shost_recovery)
-                               return;
-                       goto retry_expander_search;
-               }
+                   SAS_FANOUT_EXPANDER_DEVICE)
+                       mpt2sas_expander_remove(ioc,
+                           mpt2sas_port->remote_identify.sas_address);
        }
 
        mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
@@ -6548,7 +6492,6 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
            sas_expander->handle, (unsigned long long)
            sas_expander->sas_address);
 
-       list_del(&sas_expander->list);
        kfree(sas_expander->phy);
        kfree(sas_expander);
 }
@@ -6666,9 +6609,7 @@ _scsih_remove(struct pci_dev *pdev)
 {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
-       struct _sas_port *mpt2sas_port;
-       struct _sas_device *sas_device;
-       struct _sas_node *expander_sibling;
+       struct _sas_port *mpt2sas_port, *next_port;
        struct _raid_device *raid_device, *next;
        struct MPT2SAS_TARGET *sas_target_priv_data;
        struct workqueue_struct *wq;
@@ -6700,28 +6641,18 @@ _scsih_remove(struct pci_dev *pdev)
        }
 
        /* free ports attached to the sas_host */
- retry_again:
-       list_for_each_entry(mpt2sas_port,
+       list_for_each_entry_safe(mpt2sas_port, next_port,
           &ioc->sas_hba.sas_port_list, port_list) {
                if (mpt2sas_port->remote_identify.device_type ==
-                   SAS_END_DEVICE) {
-                       sas_device =
-                           mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
-                          mpt2sas_port->remote_identify.sas_address);
-                       if (sas_device) {
-                               _scsih_remove_device(ioc, sas_device);
-                               goto retry_again;
-                       }
-               } else {
-                       expander_sibling =
-                           mpt2sas_scsih_expander_find_by_sas_address(ioc,
+                   SAS_END_DEVICE)
+                       mpt2sas_device_remove(ioc,
+                           mpt2sas_port->remote_identify.sas_address);
+               else if (mpt2sas_port->remote_identify.device_type ==
+                   SAS_EDGE_EXPANDER_DEVICE ||
+                   mpt2sas_port->remote_identify.device_type ==
+                   SAS_FANOUT_EXPANDER_DEVICE)
+                       mpt2sas_expander_remove(ioc,
                            mpt2sas_port->remote_identify.sas_address);
-                       if (expander_sibling) {
-                               _scsih_expander_remove(ioc,
-                                   expander_sibling->sas_address);
-                               goto retry_again;
-                       }
-               }
        }
 
        /* free phys attached to the sas_host */
index b55c6dc07470cc65aed1a30979f0e61e86a16aec..cb1cdecbe0f881b83b0f6825724b725bb1632be3 100644 (file)
@@ -465,62 +465,149 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
        return rc;
 }
 
+/**
+ * _transport_delete_port - helper function to removing a port
+ * @ioc: per adapter object
+ * @mpt2sas_port: mpt2sas per port object
+ *
+ * Returns nothing.
+ */
+static void
+_transport_delete_port(struct MPT2SAS_ADAPTER *ioc,
+       struct _sas_port *mpt2sas_port)
+{
+       u64 sas_address = mpt2sas_port->remote_identify.sas_address;
+       enum sas_device_type device_type =
+           mpt2sas_port->remote_identify.device_type;
+
+       dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
+           "remove: sas_addr(0x%016llx)\n",
+           (unsigned long long) sas_address);
+
+       ioc->logging_level |= MPT_DEBUG_TRANSPORT;
+       if (device_type == SAS_END_DEVICE)
+               mpt2sas_device_remove(ioc, sas_address);
+       else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
+           device_type == SAS_FANOUT_EXPANDER_DEVICE)
+               mpt2sas_expander_remove(ioc, sas_address);
+       ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
+}
 
 /**
- * _transport_delete_duplicate_port - (see below description)
+ * _transport_delete_phy - helper function to removing single phy from port
  * @ioc: per adapter object
- * @sas_node: sas node object (either expander or sas host)
- * @sas_address: sas address of device being added
- * @phy_num: phy number
+ * @mpt2sas_port: mpt2sas per port object
+ * @mpt2sas_phy: mpt2sas per phy object
  *
- * This function is called when attempting to add a new port that is claiming
- * the same phy resources already in use by another port.  If we don't release
- * the claimed phy resources, the sas transport layer will hang from the BUG
- * in sas_port_add_phy.
+ * Returns nothing.
+ */
+static void
+_transport_delete_phy(struct MPT2SAS_ADAPTER *ioc,
+       struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy)
+{
+       u64 sas_address = mpt2sas_port->remote_identify.sas_address;
+
+       dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
+           "remove: sas_addr(0x%016llx), phy(%d)\n",
+           (unsigned long long) sas_address, mpt2sas_phy->phy_id);
+
+       list_del(&mpt2sas_phy->port_siblings);
+       mpt2sas_port->num_phys--;
+       sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
+       mpt2sas_phy->phy_belongs_to_port = 0;
+}
+
+/**
+ * _transport_add_phy - helper function to adding single phy to port
+ * @ioc: per adapter object
+ * @mpt2sas_port: mpt2sas per port object
+ * @mpt2sas_phy: mpt2sas per phy object
  *
- * The reason we would hit this issue is becuase someone is changing the
- * sas address of a device on the fly, meanwhile controller firmware sends
- * EVENTs out of order when removing the previous instance of the device.
+ * Returns nothing.
  */
 static void
-_transport_delete_duplicate_port(struct MPT2SAS_ADAPTER *ioc,
-    struct _sas_node *sas_node, u64 sas_address, int phy_num)
+_transport_add_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port,
+       struct _sas_phy *mpt2sas_phy)
 {
-       struct _sas_port *mpt2sas_port, *mpt2sas_port_duplicate;
-       struct _sas_phy *mpt2sas_phy;
+       u64 sas_address = mpt2sas_port->remote_identify.sas_address;
 
-       printk(MPT2SAS_ERR_FMT "new device located at sas_addr(0x%016llx), "
-           "phy_id(%d)\n", ioc->name, (unsigned long long)sas_address,
-           phy_num);
+       dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
+           "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
+           sas_address, mpt2sas_phy->phy_id);
 
-       mpt2sas_port_duplicate = NULL;
-       list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list, port_list) {
-               dev_printk(KERN_ERR, &mpt2sas_port->port->dev,
-                   "existing device at sas_addr(0x%016llx), num_phys(%d)\n",
-                   (unsigned long long)
-                   mpt2sas_port->remote_identify.sas_address,
-                   mpt2sas_port->num_phys);
-               list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list,
+       list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list);
+       mpt2sas_port->num_phys++;
+       sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy);
+       mpt2sas_phy->phy_belongs_to_port = 1;
+}
+
+/**
+ * _transport_add_phy_to_an_existing_port - adding new phy to existing port
+ * @ioc: per adapter object
+ * @sas_node: sas node object (either expander or sas host)
+ * @mpt2sas_phy: mpt2sas per phy object
+ * @sas_address: sas address of device/expander were phy needs to be added to
+ *
+ * Returns nothing.
+ */
+static void
+_transport_add_phy_to_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
+struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, u64 sas_address)
+{
+       struct _sas_port *mpt2sas_port;
+       struct _sas_phy *phy_srch;
+
+       if (mpt2sas_phy->phy_belongs_to_port == 1)
+               return;
+
+       list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list,
+           port_list) {
+               if (mpt2sas_port->remote_identify.sas_address !=
+                   sas_address)
+                       continue;
+               list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
                    port_siblings) {
-                       dev_printk(KERN_ERR, &mpt2sas_phy->phy->dev,
-                           "phy_number(%d)\n", mpt2sas_phy->phy_id);
-                       if (mpt2sas_phy->phy_id == phy_num)
-                               mpt2sas_port_duplicate = mpt2sas_port;
+                       if (phy_srch == mpt2sas_phy)
+                               return;
                }
+               _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy);
+                       return;
        }
 
-       if (!mpt2sas_port_duplicate)
+}
+
+/**
+ * _transport_del_phy_from_an_existing_port - delete phy from existing port
+ * @ioc: per adapter object
+ * @sas_node: sas node object (either expander or sas host)
+ * @mpt2sas_phy: mpt2sas per phy object
+ *
+ * Returns nothing.
+ */
+static void
+_transport_del_phy_from_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
+       struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy)
+{
+       struct _sas_port *mpt2sas_port, *next;
+       struct _sas_phy *phy_srch;
+
+       if (mpt2sas_phy->phy_belongs_to_port == 0)
                return;
 
-       dev_printk(KERN_ERR, &mpt2sas_port_duplicate->port->dev,
-           "deleting duplicate device at sas_addr(0x%016llx), phy(%d)!!!!\n",
-           (unsigned long long)
-           mpt2sas_port_duplicate->remote_identify.sas_address, phy_num);
-       ioc->logging_level |= MPT_DEBUG_TRANSPORT;
-       mpt2sas_transport_port_remove(ioc,
-           mpt2sas_port_duplicate->remote_identify.sas_address,
-           sas_node->sas_address);
-       ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
+       list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
+           port_list) {
+               list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
+                   port_siblings) {
+                       if (phy_srch != mpt2sas_phy)
+                               continue;
+                       if (mpt2sas_port->num_phys == 1)
+                               _transport_delete_port(ioc, mpt2sas_port);
+                       else
+                               _transport_delete_phy(ioc, mpt2sas_port,
+                                   mpt2sas_phy);
+                       return;
+               }
+       }
 }
 
 /**
@@ -537,11 +624,13 @@ _transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node,
 {
        int i;
 
-       for (i = 0; i < sas_node->num_phys; i++)
-               if (sas_node->phy[i].remote_identify.sas_address == sas_address)
-                       if (sas_node->phy[i].phy_belongs_to_port)
-                               _transport_delete_duplicate_port(ioc, sas_node,
-                                       sas_address, i);
+       for (i = 0; i < sas_node->num_phys; i++) {
+               if (sas_node->phy[i].remote_identify.sas_address != sas_address)
+                       continue;
+               if (sas_node->phy[i].phy_belongs_to_port == 1)
+                       _transport_del_phy_from_an_existing_port(ioc, sas_node,
+                           &sas_node->phy[i]);
+       }
 }
 
 /**
@@ -905,10 +994,12 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
 
        mpt2sas_phy = &sas_node->phy[phy_number];
        mpt2sas_phy->attached_handle = handle;
-       if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
+       if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
                _transport_set_identify(ioc, handle,
                    &mpt2sas_phy->remote_identify);
-       else
+               _transport_add_phy_to_an_existing_port(ioc, sas_node,
+                   mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address);
+       } else
                memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
                    sas_identify));
 
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 0433ea6f27c9c2db97c464ca238afce39ebd0fcb..b37c8a3c1bb0de6d1b64fdf9ea3cbb8357f13805 100644 (file)
@@ -951,8 +951,8 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key)
        /* create a bio for continuation segment */
        bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes,
                           GFP_KERNEL);
-       if (unlikely(!bio))
-               return -ENOMEM;
+       if (IS_ERR(bio))
+               return PTR_ERR(bio);
 
        bio->bi_rw |= REQ_WRITE;
 
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..300d59f389da76175ac4720fc2d9a69b0a16b163 100644 (file)
@@ -62,6 +62,7 @@
 static unsigned int pmcraid_debug_log;
 static unsigned int pmcraid_disable_aen;
 static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST;
+static unsigned int pmcraid_enable_msix;
 
 /*
  * Data structures to support multiple adapters by the LLD.
@@ -3478,7 +3479,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 +3585,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
  */
@@ -4689,7 +4692,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
        int rc;
        struct pci_dev *pdev = pinstance->pdev;
 
-       if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+       if ((pmcraid_enable_msix) &&
+               (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) {
                int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
                struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
                int i;
index 1134279604e805780f84607c523bbdd647685f24..4db210d93947275efd67e493549d75162fdf21e1 100644 (file)
@@ -42,7 +42,7 @@
  */
 #define PMCRAID_DRIVER_NAME            "PMC MaxRAID"
 #define PMCRAID_DEVFILE                        "pmcsas"
-#define PMCRAID_DRIVER_VERSION         "2.0.3"
+#define PMCRAID_DRIVER_VERSION         "1.0.3"
 #define PMCRAID_DRIVER_DATE            __DATE__
 
 #define PMCRAID_FW_VERSION_1           0x002
@@ -333,11 +333,9 @@ struct pmcraid_config_table_entry {
        __u8  lun[PMCRAID_LUN_LEN];
 } __attribute__((packed, aligned(4)));
 
-/* extended configuration table sizes are of 64 bytes in size */
-#define PMCRAID_CFGTE_EXT_SIZE 32
+/* extended configuration table sizes are also of 32 bytes in size */
 struct pmcraid_config_table_entry_ext {
        struct pmcraid_config_table_entry cfgte;
-       __u8  cfgte_ext[PMCRAID_CFGTE_EXT_SIZE];
 };
 
 /* resource types (config_table_entry.resource_type values) */
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 3a22effced5fa1a94996582b9fd13ccf151d8861..9ce539d4557e2a18d495ec2a31366cf5ebccc4aa 100644 (file)
@@ -2409,7 +2409,6 @@ struct qla_hw_data {
                uint32_t        enable_target_reset     :1;
                uint32_t        enable_lip_full_login   :1;
                uint32_t        enable_led_scheme       :1;
-               uint32_t        inta_enabled            :1;
                uint32_t        msi_enabled             :1;
                uint32_t        msix_enabled            :1;
                uint32_t        disable_serdes          :1;
index 5f94430b42f03974fda76e9f1f969cedbf3e9047..4c1ba6263eb32c1a228f2044b314c4e902f1c677 100644 (file)
@@ -1061,6 +1061,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
                fcp_cmnd->additional_cdb_len |= 2;
 
        int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun);
+       host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun));
        memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
        cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
        cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32(
index 1f06ddd9bdd10cdbe6526de1deaaab194a19118e..7f77898486a9014f1e4848e77648f78c5dce1c75 100644 (file)
@@ -2491,14 +2491,15 @@ skip_msix:
 skip_msi:
 
        ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
-           IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
+           ha->flags.msi_enabled ? 0 : IRQF_SHARED,
+           QLA2XXX_DRIVER_NAME, rsp);
        if (ret) {
                qla_printk(KERN_WARNING, ha,
                    "Failed to reserve interrupt %d already in use.\n",
                    ha->pdev->irq);
                goto fail;
        }
-       ha->flags.inta_enabled = 1;
+
 clear_risc_ints:
 
        /*
index 8d9edfb39803ff26809743ef8cf5e0b22abd305b..ae2acacc00036558c5ddb0e246e8b691097c80ca 100644 (file)
@@ -2749,6 +2749,7 @@ sufficient_dsds:
                        goto queuing_error_fcp_cmnd;
 
                int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+               host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
 
                /* build FCP_CMND IU */
                memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
index 1830e6e973155684234710e129e564f82176ce2d..2c0876c81a3f6e5793d504b825146b6de7c2ae81 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
@@ -828,7 +829,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 {
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        srb_t *sp;
-       int ret;
+       int ret = SUCCESS;
        unsigned int id, lun;
        unsigned long flags;
        int wait = 0;
@@ -2063,6 +2064,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
                ha->gid_list_info_size = 8;
                ha->optrom_size = OPTROM_SIZE_82XX;
+               ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
                ha->isp_ops = &qla82xx_isp_ops;
                ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
                ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
index 8edbccb3232d3b68cb16d0054a444e657a452975..cf0075a2d0c2e66d93146bd92d95a5811f021327 100644 (file)
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.04-k0"
+#define QLA2XXX_VERSION      "8.03.05-k0"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   3
-#define QLA_DRIVER_PATCH_VER   4
+#define QLA_DRIVER_PATCH_VER   5
 #define QLA_DRIVER_BETA_VER    0
index edcf048215dd18326181a8cdca07acf3198b3cb3..af62c3cf875293c08f53817febd08cd5961b24a4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index d861c3b411c88746e837915a62009a13205ca222..abd83602cddaebee3712bb7c2906c04256317959 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index 0f3bfc3da5cf6670287393bb4ca64baee59db2e4..2fc0045b1a5257c8ef65edc41d68d1929b86cd36 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 struct srb {
        struct list_head list;  /* (8)   */
        struct scsi_qla_host *ha;       /* HA the SP is queued on */
-       struct ddb_entry        *ddb;
+       struct ddb_entry *ddb;
        uint16_t flags;         /* (1) Status flags. */
 
 #define SRB_DMA_VALID          BIT_3   /* DMA Buffer mapped. */
@@ -191,7 +191,6 @@ struct srb {
        struct scsi_cmnd *cmd;  /* (4) SCSI command block */
        dma_addr_t dma_handle;  /* (4) for unmap of single transfers */
        struct kref srb_ref;    /* reference count for this srb */
-       uint32_t fw_ddb_index;
        uint8_t err_id;         /* error id */
 #define SRB_ERR_PORT      1    /* Request failed because "port down" */
 #define SRB_ERR_LOOP      2    /* Request failed because "loop down" */
index 5e757d7fff7dc4eb0ae23d01ec93c4b6550d1ce6..c1985792f03423e71f3f959da28817a37cf0d835 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index 6575a47501e57667f3f7c8dc2cae73c7c7fb5876..8fad99b7eef4c6edd2d206a1e8826f93e691ee13 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index dc01fa3da5d11be799f2c826bc324424e2bd3b76..1629c48c35ef040aefbfd0945a57798c01119cc6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index 9471ac75500092cd4a47fb81e3674a7a7983d2b2..62f90bdec5d542a7177b3c532d8c20d4039f3f95 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index 5ae49fd8784639c8802e24c8ce210fd0f9cf1ee0..75fcd82a8fcae40b2f56bec6d7aeacb67cbe50ee 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index 7c33fd5943d50315a22ac5ff64de69799fe795a2..6ffbe9727dffb5c670b93731d2d121446b7d72b6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
@@ -554,7 +554,8 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
                        /* mbox_sts[2] = Old ACB state
                         * mbox_sts[3] = new ACB state */
                        if ((mbox_sts[3] == ACB_STATE_VALID) &&
-                           (mbox_sts[2] == ACB_STATE_TENTATIVE))
+                           ((mbox_sts[2] == ACB_STATE_TENTATIVE) ||
+                           (mbox_sts[2] == ACB_STATE_ACQUIRING)))
                                set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
                        else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) &&
                            (mbox_sts[2] == ACB_STATE_VALID))
@@ -1077,7 +1078,7 @@ try_msi:
        ret = pci_enable_msi(ha->pdev);
        if (!ret) {
                ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler,
-                       IRQF_DISABLED|IRQF_SHARED, DRIVER_NAME, ha);
+                       0, DRIVER_NAME, ha);
                if (!ret) {
                        DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
                        set_bit(AF_MSI_ENABLED, &ha->flags);
@@ -1095,7 +1096,7 @@ try_msi:
 try_intx:
        /* Trying INTx */
        ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
-           IRQF_DISABLED|IRQF_SHARED, DRIVER_NAME, ha);
+           IRQF_SHARED, DRIVER_NAME, ha);
        if (!ret) {
                DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n"));
                set_bit(AF_INTx_ENABLED, &ha->flags);
index 2d2f9c879bfd57994366e050f9a82bc2541a4030..f65626aec7c18bace0701f7b43551f2c4f8eb817 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
@@ -81,23 +81,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
         */
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
-       if (is_qla8022(ha)) {
-               intr_status = readl(&ha->qla4_8xxx_reg->host_int);
-               if (intr_status & ISRX_82XX_RISC_INT) {
-                       /* Service existing interrupt */
-                       DEBUG2(printk("scsi%ld: %s: "
-                           "servicing existing interrupt\n",
-                           ha->host_no, __func__));
-                       intr_status = readl(&ha->qla4_8xxx_reg->host_status);
-                       ha->isp_ops->interrupt_service_routine(ha, intr_status);
-                       clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
-                       if (test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
-                           test_bit(AF_INTx_ENABLED, &ha->flags))
-                               qla4_8xxx_wr_32(ha,
-                                   ha->nx_legacy_intr.tgt_mask_reg,
-                                   0xfbff);
-               }
-       } else {
+       if (!is_qla8022(ha)) {
                intr_status = readl(&ha->reg->ctrl_status);
                if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
                        /* Service existing interrupt */
@@ -934,7 +918,7 @@ int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)
                return status;
 
        mbox_cmd[0] = MBOX_CMD_ABORT_TASK;
-       mbox_cmd[1] = srb->fw_ddb_index;
+       mbox_cmd[1] = srb->ddb->fw_ddb_index;
        mbox_cmd[2] = index;
        /* Immediate Command Enable */
        mbox_cmd[5] = 0x01;
index f0d0fbf88aa239e320f45f84a853a7b1b414fe37..b4b859b2d47e4ea3db32dc87ede44ca4bdf40e45 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index 7a8fc66a760dfbbcf840a536e02871415a3f0826..b3831bd2947986e4183bfdb56ae1ab409aa0228a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
index 474b10d713647ea8aafde7a9057a49450bcf99e9..3d5ef2df4134b84763a7f671fc630438844e2810 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2009 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
@@ -942,12 +942,55 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
 
        /* Halt all the indiviual PEGs and other blocks of the ISP */
        qla4_8xxx_rom_lock(ha);
+
+       /* mask all niu interrupts */
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
+       /* disable xge rx/tx */
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
+       /* disable xg1 rx/tx */
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
+
+       /* halt sre */
+       val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_SRE + 0x1000, val & (~(0x1)));
+
+       /* halt epg */
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_EPG + 0x1300, 0x1);
+
+       /* halt timers */
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x0, 0x0);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x8, 0x0);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
+
+       /* halt pegs */
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c, 1);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
+
+       /* big hammer */
+       msleep(1000);
        if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
                /* don't reset CAM block on reset */
                qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
        else
                qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
 
+       /* reset ms */
+       val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
+       val |= (1 << 1);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
+
+       msleep(20);
+       /* unreset ms */
+       val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
+       val &= ~(1 << 1);
+       qla4_8xxx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
+       msleep(20);
+
        qla4_8xxx_rom_unlock(ha);
 
        /* Read the signature value from the flash.
@@ -1084,14 +1127,14 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
 static int
 qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
 {
-       int  i;
+       int  i, rval = 0;
        long size = 0;
        long flashaddr, memaddr;
        u64 data;
        u32 high, low;
 
        flashaddr = memaddr = ha->hw.flt_region_bootload;
-       size = (image_start - flashaddr)/8;
+       size = (image_start - flashaddr) / 8;
 
        DEBUG2(printk("scsi%ld: %s: bootldr=0x%lx, fw_image=0x%x\n",
            ha->host_no, __func__, flashaddr, image_start));
@@ -1100,14 +1143,18 @@ qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
                if ((qla4_8xxx_rom_fast_read(ha, flashaddr, (int *)&low)) ||
                    (qla4_8xxx_rom_fast_read(ha, flashaddr + 4,
                    (int *)&high))) {
-                       return -1;
+                       rval = -1;
+                       goto exit_load_from_flash;
                }
                data = ((u64)high << 32) | low ;
-               qla4_8xxx_pci_mem_write_2M(ha, memaddr, &data, 8);
+               rval = qla4_8xxx_pci_mem_write_2M(ha, memaddr, &data, 8);
+               if (rval)
+                       goto exit_load_from_flash;
+
                flashaddr += 8;
                memaddr   += 8;
 
-               if (i%0x1000 == 0)
+               if (i % 0x1000 == 0)
                        msleep(1);
 
        }
@@ -1119,7 +1166,8 @@ qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
        qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);
        read_unlock(&ha->hw_lock);
 
-       return 0;
+exit_load_from_flash:
+       return rval;
 }
 
 static int qla4_8xxx_load_fw(struct scsi_qla_host *ha, uint32_t image_start)
index ff689bf530071a1978fe85bce5e56082b2570e8b..35376a1c3f1bc109fb8bea9deb54cec9b7acf0c8 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2008 QLogic Corporation
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
- * See LICENSE.qla2xxx for copyright and licensing details.
+ * See LICENSE.qla4xxx for copyright and licensing details.
  */
 #ifndef __QLA_NX_H
 #define __QLA_NX_H
index f4cd846abf6dcf77dc7d6bd7a855437ba6a1868f..3fc1d256636fa0ce9a0155a734238eef49b1e935 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
@@ -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.
@@ -705,18 +706,22 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
        dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
 
        /* don't poll if reset is going on */
-       if (!test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags)) {
+       if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||
+           test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
+           test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags))) {
                if (dev_state == QLA82XX_DEV_NEED_RESET &&
                    !test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
-                       printk("scsi%ld: %s: HW State: NEED RESET!\n",
-                           ha->host_no, __func__);
-                       set_bit(DPC_RESET_HA, &ha->dpc_flags);
-                       qla4xxx_wake_dpc(ha);
-                       qla4xxx_mailbox_premature_completion(ha);
+                       if (!ql4xdontresethba) {
+                               ql4_printk(KERN_INFO, ha, "%s: HW State: "
+                                   "NEED RESET!\n", __func__);
+                               set_bit(DPC_RESET_HA, &ha->dpc_flags);
+                               qla4xxx_wake_dpc(ha);
+                               qla4xxx_mailbox_premature_completion(ha);
+                       }
                } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
                    !test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) {
-                       printk("scsi%ld: %s: HW State: NEED QUIES!\n",
-                           ha->host_no, __func__);
+                       ql4_printk(KERN_INFO, ha, "%s: HW State: NEED QUIES!\n",
+                           __func__);
                        set_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags);
                        qla4xxx_wake_dpc(ha);
                } else  {
@@ -1720,6 +1725,14 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
        if (!test_bit(AF_ONLINE, &ha->flags)) {
                ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n");
 
+               if (is_qla8022(ha) && ql4xdontresethba) {
+                       /* Put the device in failed state. */
+                       DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n"));
+                       qla4_8xxx_idc_lock(ha);
+                       qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+                           QLA82XX_DEV_FAILED);
+                       qla4_8xxx_idc_unlock(ha);
+               }
                ret = -ENODEV;
                goto probe_failed;
        }
index 9bfacf4ed1371f30a557ac99250feb8e2d3f0987..8475b308e01b082375008834de93323b552a71be 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * QLogic iSCSI HBA Driver
- * Copyright (c)  2003-2006 QLogic Corporation
+ * Copyright (c)  2003-2010 QLogic Corporation
  *
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION "5.02.00-k4"
+#define QLA4XXX_DRIVER_VERSION "5.02.00-k5"
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..7b310934efed5509bbc7d78969ad912874c0140e 100644 (file)
@@ -1805,6 +1805,7 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
                        devip->sense_buff[5] = (ret >> 8) & 0xff;
                        devip->sense_buff[6] = ret & 0xff;
                }
+               scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
                return check_condition_result;
        }
 
@@ -3538,7 +3539,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 +3885,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..45c75649b9e083e489e1a935a2617a8d0461749f 100644 (file)
@@ -615,7 +615,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
        return rtn;
 }
 
-static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
+static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
 {
        if (!scmd->device->host->hostt->eh_abort_handler)
                return FAILED;
@@ -623,31 +623,9 @@ static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
        return scmd->device->host->hostt->eh_abort_handler(scmd);
 }
 
-/**
- * scsi_try_to_abort_cmd - Ask host to abort a running command.
- * @scmd:      SCSI cmd to abort from Lower Level.
- *
- * Notes:
- *    This function will not return until the user's completion function
- *    has been called.  there is no timeout on this operation.  if the
- *    author of the low-level driver wishes this operation to be timed,
- *    they can provide this facility themselves.  helper functions in
- *    scsi_error.c can be supplied to make this easier to do.
- */
-static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
-{
-       /*
-        * scsi_done was called just after the command timed out and before
-        * we had a chance to process it. (db)
-        */
-       if (scmd->serial_number == 0)
-               return SUCCESS;
-       return __scsi_try_to_abort_cmd(scmd);
-}
-
 static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
 {
-       if (__scsi_try_to_abort_cmd(scmd) != SUCCESS)
+       if (scsi_try_to_abort_cmd(scmd) != SUCCESS)
                if (scsi_try_bus_device_reset(scmd) != SUCCESS)
                        if (scsi_try_target_reset(scmd) != SUCCESS)
                                if (scsi_try_bus_reset(scmd) != SUCCESS)
@@ -773,17 +751,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);
 
@@ -1148,51 +1124,40 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
                                struct list_head *work_q,
                                struct list_head *done_q)
 {
-       struct scsi_cmnd *scmd, *tgtr_scmd, *next;
-       unsigned int id = 0;
-       int rtn;
+       LIST_HEAD(tmp_list);
 
-       do {
-               tgtr_scmd = NULL;
-               list_for_each_entry(scmd, work_q, eh_entry) {
-                       if (id == scmd_id(scmd)) {
-                               tgtr_scmd = scmd;
-                               break;
-                       }
-               }
-               if (!tgtr_scmd) {
-                       /* not one exactly equal; find the next highest */
-                       list_for_each_entry(scmd, work_q, eh_entry) {
-                               if (scmd_id(scmd) > id &&
-                                   (!tgtr_scmd ||
-                                    scmd_id(tgtr_scmd) > scmd_id(scmd)))
-                                               tgtr_scmd = scmd;
-                       }
-               }
-               if (!tgtr_scmd)
-                       /* no more commands, that's it */
-                       break;
+       list_splice_init(work_q, &tmp_list);
+
+       while (!list_empty(&tmp_list)) {
+               struct scsi_cmnd *next, *scmd;
+               int rtn;
+               unsigned int id;
+
+               scmd = list_entry(tmp_list.next, struct scsi_cmnd, eh_entry);
+               id = scmd_id(scmd);
 
                SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset "
                                                  "to target %d\n",
                                                  current->comm, id));
-               rtn = scsi_try_target_reset(tgtr_scmd);
-               if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
-                       list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
-                               if (id == scmd_id(scmd))
-                                       if (!scsi_device_online(scmd->device) ||
-                                           rtn == FAST_IO_FAIL ||
-                                           !scsi_eh_tur(tgtr_scmd))
-                                               scsi_eh_finish_cmd(scmd,
-                                                                  done_q);
-                       }
-               } else
+               rtn = scsi_try_target_reset(scmd);
+               if (rtn != SUCCESS && rtn != FAST_IO_FAIL)
                        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Target reset"
                                                          " failed target: "
                                                          "%d\n",
                                                          current->comm, id));
-               id++;
-       } while(id != 0);
+               list_for_each_entry_safe(scmd, next, &tmp_list, eh_entry) {
+                       if (scmd_id(scmd) != id)
+                               continue;
+
+                       if ((rtn == SUCCESS || rtn == FAST_IO_FAIL)
+                           && (!scsi_device_online(scmd->device) ||
+                                rtn == FAST_IO_FAIL || !scsi_eh_tur(scmd)))
+                               scsi_eh_finish_cmd(scmd, done_q);
+                       else
+                               /* push back on work queue for further processing */
+                               list_move(&scmd->eh_entry, work_q);
+               }
+       }
 
        return list_empty(work_q);
 }
index 13bf89145b18b883d3b31bb855a36e743d46b9e0..b702b446d151690fa0a911422ad598b5ea396925 100644 (file)
@@ -1278,11 +1278,10 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
        }
 
        if (scsi_target_is_busy(starget)) {
-               if (list_empty(&sdev->starved_entry)) {
+               if (list_empty(&sdev->starved_entry))
                        list_add_tail(&sdev->starved_entry,
                                      &shost->starved_list);
-                       return 0;
-               }
+               return 0;
        }
 
        /* We're OK to process the command, so we can't be starved */
@@ -1403,11 +1402,6 @@ static void scsi_softirq_done(struct request *rq)
 
        INIT_LIST_HEAD(&cmd->eh_entry);
 
-       /*
-        * Set the serial numbers back to zero
-        */
-       cmd->serial_number = 0;
-
        atomic_inc(&cmd->device->iodone_cnt);
        if (cmd->result)
                atomic_inc(&cmd->device->ioerr_cnt);
index 332387a6bc25de2210a6137c9ccdd4c1e34a6bd0..f905ecb5704d71b0c9a5fd81fe0c88f0c2970fb3 100644 (file)
@@ -2200,3 +2200,4 @@ MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
 MODULE_DESCRIPTION("iSCSI Transport Interface");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(ISCSI_TRANSPORT_VERSION);
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_ISCSI);
index 8d488a9fef008453c4632993d15503f0cb1f2075..b65e65aa07eb12ab1d2c8006a13308442f644e20 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>
@@ -584,7 +583,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
                 * quietly refuse to do anything to a changed disc until 
                 * the changed bit has been reset
                 */
-               /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
+               /* printk("SCSI disk has been changed or is not present. Prohibiting further I/O.\n"); */
                goto out;
        }
 
@@ -1024,7 +1023,6 @@ static int sd_media_changed(struct gendisk *disk)
         */
        if (!scsi_device_online(sdp)) {
                set_media_not_present(sdkp);
-               retval = 1;
                goto out;
        }
 
@@ -1047,7 +1045,6 @@ static int sd_media_changed(struct gendisk *disk)
 
        if (retval) {
                set_media_not_present(sdkp);
-               retval = 1;
                goto out;
        }
 
@@ -1058,12 +1055,27 @@ static int sd_media_changed(struct gendisk *disk)
         */
        sdkp->media_present = 1;
 
-       retval = sdp->changed;
-       sdp->changed = 0;
 out:
-       if (retval != sdkp->previous_state)
+       /*
+        * Report a media change under the following conditions:
+        *
+        *      Medium is present now and wasn't present before.
+        *      Medium wasn't present before and is present now.
+        *      Medium was present at all times, but it changed while
+        *              we weren't looking (sdp->changed is set).
+        *
+        * If there was no medium before and there is no medium now then
+        * don't report a change, even if a medium was inserted and removed
+        * while we weren't looking.
+        */
+       retval = (sdkp->media_present != sdkp->previous_state ||
+                       (sdkp->media_present && sdp->changed));
+       if (retval)
                sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL);
-       sdkp->previous_state = retval;
+       sdkp->previous_state = sdkp->media_present;
+
+       /* sdp->changed indicates medium was changed or is not present */
+       sdp->changed = !sdkp->media_present;
        kfree(sshdr);
        return retval;
 }
@@ -1168,6 +1180,12 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
        u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512);
        u64 bad_lba;
        int info_valid;
+       /*
+        * resid is optional but mostly filled in.  When it's unused,
+        * its value is zero, so we assume the whole buffer transferred
+        */
+       unsigned int transferred = scsi_bufflen(scmd) - scsi_get_resid(scmd);
+       unsigned int good_bytes;
 
        if (scmd->request->cmd_type != REQ_TYPE_FS)
                return 0;
@@ -1201,7 +1219,8 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
        /* This computation should always be done in terms of
         * the resolution of the device's medium.
         */
-       return (bad_lba - start_lba) * scmd->device->sector_size;
+       good_bytes = (bad_lba - start_lba) * scmd->device->sector_size;
+       return min(good_bytes, transferred);
 }
 
 /**
@@ -1895,10 +1914,14 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
        int old_rcd = sdkp->RCD;
        int old_dpofua = sdkp->DPOFUA;
 
-       if (sdp->skip_ms_page_8)
-               goto defaults;
-
-       if (sdp->type == TYPE_RBC) {
+       if (sdp->skip_ms_page_8) {
+               if (sdp->type == TYPE_RBC)
+                       goto defaults;
+               else {
+                       modepage = 0x3F;
+                       dbd = 0;
+               }
+       } else if (sdp->type == TYPE_RBC) {
                modepage = 6;
                dbd = 8;
        } else {
@@ -1926,13 +1949,11 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
         */
        if (len < 3)
                goto bad_sense;
-       if (len > 20)
-               len = 20;
-
-       /* Take headers and block descriptors into account */
-       len += data.header_length + data.block_descriptor_length;
-       if (len > SD_BUF_SIZE)
-               goto bad_sense;
+       else if (len > SD_BUF_SIZE) {
+               sd_printk(KERN_NOTICE, sdkp, "Truncating mode parameter "
+                         "data from %d to %d bytes\n", len, SD_BUF_SIZE);
+               len = SD_BUF_SIZE;
+       }
 
        /* Get the data */
        res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
@@ -1940,16 +1961,45 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
        if (scsi_status_is_good(res)) {
                int offset = data.header_length + data.block_descriptor_length;
 
-               if (offset >= SD_BUF_SIZE - 2) {
-                       sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n");
-                       goto defaults;
+               while (offset < len) {
+                       u8 page_code = buffer[offset] & 0x3F;
+                       u8 spf       = buffer[offset] & 0x40;
+
+                       if (page_code == 8 || page_code == 6) {
+                               /* We're interested only in the first 3 bytes.
+                                */
+                               if (len - offset <= 2) {
+                                       sd_printk(KERN_ERR, sdkp, "Incomplete "
+                                                 "mode parameter data\n");
+                                       goto defaults;
+                               } else {
+                                       modepage = page_code;
+                                       goto Page_found;
+                               }
+                       } else {
+                               /* Go to the next page */
+                               if (spf && len - offset > 3)
+                                       offset += 4 + (buffer[offset+2] << 8) +
+                                               buffer[offset+3];
+                               else if (!spf && len - offset > 1)
+                                       offset += 2 + buffer[offset+1];
+                               else {
+                                       sd_printk(KERN_ERR, sdkp, "Incomplete "
+                                                 "mode parameter data\n");
+                                       goto defaults;
+                               }
+                       }
                }
 
-               if ((buffer[offset] & 0x3f) != modepage) {
+               if (modepage == 0x3F) {
+                       sd_printk(KERN_ERR, sdkp, "No Caching mode page "
+                                 "present\n");
+                       goto defaults;
+               } else if ((buffer[offset] & 0x3f) != modepage) {
                        sd_printk(KERN_ERR, sdkp, "Got wrong page\n");
                        goto defaults;
                }
-
+       Page_found:
                if (modepage == 8) {
                        sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
                        sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
index 5b7388f1c83545975b4ebcad9a73f62cb7669f36..1871b8ae83ae7031f73084470278c7a89ce8da96 100644 (file)
@@ -17,7 +17,7 @@
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static const char *verstr = "20100829";
+static const char *verstr = "20101219";
 
 #include <linux/module.h>
 
@@ -3729,9 +3729,11 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
                b_size = PAGE_SIZE << order;
        } else {
                for (b_size = PAGE_SIZE, order = 0;
-                    order < ST_MAX_ORDER && b_size < new_size;
+                    order < ST_MAX_ORDER &&
+                            max_segs * (PAGE_SIZE << order) < new_size;
                     order++, b_size *= 2)
                        ;  /* empty */
+               STbuffer->reserved_page_order = order;
        }
        if (max_segs * (PAGE_SIZE << order) < new_size) {
                if (order == ST_MAX_ORDER)
@@ -3758,7 +3760,6 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
                segs++;
        }
        STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
-       STbuffer->reserved_page_order = order;
 
        return 1;
 }
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 3374618300af87c16ac3ef6a674e9cb650e62f8c..25a8bc565f400b62c155dd31bb39ff08e8d85dd0 100644 (file)
@@ -90,7 +90,8 @@ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
 
 static void kgdboc_restore_input(void)
 {
-       schedule_work(&kgdboc_restore_input_work);
+       if (likely(system_state == SYSTEM_RUNNING))
+               schedule_work(&kgdboc_restore_input_work);
 }
 
 static int kgdboc_register_kbd(char **cptr)
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 90439314cf673ce19c33747ab4f283f0f3f0bc01..0838c79861e49f9a0c97189af9ab25d3c0269b76 100644 (file)
@@ -413,6 +413,11 @@ static void poll_transfer(struct dw_spi *dws)
 {
        while (dws->write(dws))
                dws->read(dws);
+       /*
+        * There is a possibility that the last word of a transaction
+        * will be lost if data is not ready. Re-read to solve this issue.
+        */
+       dws->read(dws);
 
        transfer_complete(dws);
 }
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 05bf5a27b5b0491fd7fd6feaddb24f51983317d3..989e16e4ab5c4b4057f2069927d03474e8441a5c 100644 (file)
@@ -951,7 +951,9 @@ static int usbatm_atm_init(struct usbatm_data *instance)
         * condition: callbacks we register can be executed at once, before we have
         * initialized the struct atm_dev.  To protect against this, all callbacks
         * abort if atm_dev->dev_data is NULL. */
-       atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL);
+       atm_dev = atm_dev_register(instance->driver_name,
+                                  &instance->usb_intf->dev, &usbatm_atm_devops,
+                                  -1, NULL);
        if (!atm_dev) {
                usb_err(instance, "%s: failed to register ATM device!\n", __func__);
                return -1;
@@ -966,14 +968,6 @@ static int usbatm_atm_init(struct usbatm_data *instance)
        /* temp init ATM device, set to 128kbit */
        atm_dev->link_rate = 128 * 1000 / 424;
 
-       ret = sysfs_create_link(&atm_dev->class_dev.kobj,
-                               &instance->usb_intf->dev.kobj, "device");
-       if (ret) {
-               atm_err(instance, "%s: sysfs_create_link failed: %d\n",
-                                       __func__, ret);
-               goto fail_sysfs;
-       }
-
        if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) {
                atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret);
                goto fail;
@@ -992,8 +986,6 @@ static int usbatm_atm_init(struct usbatm_data *instance)
        return 0;
 
  fail:
-       sysfs_remove_link(&atm_dev->class_dev.kobj, "device");
- fail_sysfs:
        instance->atm_dev = NULL;
        atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */
        return ret;
@@ -1329,7 +1321,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
 
        /* ATM finalize */
        if (instance->atm_dev) {
-               sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device");
                atm_dev_deregister(instance->atm_dev);
                instance->atm_dev = NULL;
        }
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 94701ff3a23ad957a9c675bd3ccd74418c2f989e..159c77a5746fecfd6c6eeb687cf11e747e194fba 100644 (file)
@@ -884,6 +884,7 @@ static int log_write(void __user *log_base,
        int r;
        if (!write_length)
                return 0;
+       write_length += write_address % VHOST_PAGE_SIZE;
        write_address /= VHOST_PAGE_SIZE;
        for (;;) {
                u64 base = (u64)(unsigned long)log_base;
@@ -897,7 +898,7 @@ static int log_write(void __user *log_base,
                if (write_length <= VHOST_PAGE_SIZE)
                        break;
                write_length -= VHOST_PAGE_SIZE;
-               write_address += VHOST_PAGE_SIZE;
+               write_address += 1;
        }
        return r;
 }
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 0a4dbdc1693a4462bddb82cdf5e0b9ab5ec4bed2..de450c1fb86926f39190f052d7644d56f60ccc5d 100644 (file)
@@ -855,6 +855,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode,
                        abs(cmode->yres - mode->yres);
                if (diff > d) {
                        diff = d;
+                       diff_refresh = abs(cmode->refresh - mode->refresh);
                        best = cmode;
                } else if (diff == d) {
                        d = abs(cmode->refresh - mode->refresh);
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 6017389711eec8d620d4e132591bcce068a68aa4..dab021db6c0b867866118367a7e2b077b6a1c8de 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..51d2e4de34ebe58d4eb5d2c99d1fc1bb83f692f9 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,27 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
                                   __btree_submit_bio_done);
 }
 
+#ifdef CONFIG_MIGRATION
+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;
+       return migrate_page(mapping, newpage, page);
+}
+#endif
+
 static int btree_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct extent_io_tree *tree;
@@ -707,8 +731,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 +822,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,
@@ -981,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
        blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
        root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
                                     blocksize, generation);
-       BUG_ON(!root->node);
+       if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
+               free_extent_buffer(root->node);
+               return -EIO;
+       }
        root->commit_root = btrfs_root_node(root);
        return 0;
 }
@@ -1538,10 +1567,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..227e5815d8382393d4adc4d0a340ee636bca9d3e 100644 (file)
@@ -429,6 +429,7 @@ err:
 
 static int cache_block_group(struct btrfs_block_group_cache *cache,
                             struct btrfs_trans_handle *trans,
+                            struct btrfs_root *root,
                             int load_cache_only)
 {
        struct btrfs_fs_info *fs_info = cache->fs_info;
@@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
 
        /*
         * We can't do the read from on-disk cache during a commit since we need
-        * to have the normal tree locking.
+        * to have the normal tree locking.  Also if we are currently trying to
+        * allocate blocks for the tree root we can't do the fast caching since
+        * we likely hold important locks.
         */
-       if (!trans->transaction->in_commit) {
+       if (!trans->transaction->in_commit &&
+           (root && root != root->fs_info->tree_root)) {
                spin_lock(&cache->lock);
                if (cache->cached != BTRFS_CACHE_NO) {
                        spin_unlock(&cache->lock);
@@ -2741,6 +2745,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
        struct btrfs_root *root = block_group->fs_info->tree_root;
        struct inode *inode = NULL;
        u64 alloc_hint = 0;
+       int dcs = BTRFS_DC_ERROR;
        int num_pages = 0;
        int retries = 0;
        int ret = 0;
@@ -2795,6 +2800,8 @@ again:
 
        spin_lock(&block_group->lock);
        if (block_group->cached != BTRFS_CACHE_FINISHED) {
+               /* We're not cached, don't bother trying to write stuff out */
+               dcs = BTRFS_DC_WRITTEN;
                spin_unlock(&block_group->lock);
                goto out_put;
        }
@@ -2821,6 +2828,8 @@ again:
        ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages,
                                              num_pages, num_pages,
                                              &alloc_hint);
+       if (!ret)
+               dcs = BTRFS_DC_SETUP;
        btrfs_free_reserved_data_space(inode, num_pages);
 out_put:
        iput(inode);
@@ -2828,10 +2837,7 @@ out_free:
        btrfs_release_path(root, path);
 out:
        spin_lock(&block_group->lock);
-       if (ret)
-               block_group->disk_cache_state = BTRFS_DC_ERROR;
-       else
-               block_group->disk_cache_state = BTRFS_DC_SETUP;
+       block_group->disk_cache_state = dcs;
        spin_unlock(&block_group->lock);
 
        return ret;
@@ -3037,7 +3043,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
 
 u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
 {
-       u64 num_devices = root->fs_info->fs_devices->rw_devices;
+       /*
+        * we add in the count of missing devices because we want
+        * to make sure that any RAID levels on a degraded FS
+        * continue to be honored.
+        */
+       u64 num_devices = root->fs_info->fs_devices->rw_devices +
+               root->fs_info->fs_devices->missing_devices;
 
        if (num_devices == 1)
                flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0);
@@ -3412,7 +3424,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;
@@ -4080,7 +4092,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                 * space back to the block group, otherwise we will leak space.
                 */
                if (!alloc && cache->cached == BTRFS_CACHE_NO)
-                       cache_block_group(cache, trans, 1);
+                       cache_block_group(cache, trans, NULL, 1);
 
                byte_in_group = bytenr - cache->key.objectid;
                WARN_ON(byte_in_group > cache->key.offset);
@@ -4930,11 +4942,31 @@ search:
                btrfs_get_block_group(block_group);
                search_start = block_group->key.objectid;
 
+               /*
+                * this can happen if we end up cycling through all the
+                * raid types, but we want to make sure we only allocate
+                * for the proper type.
+                */
+               if (!block_group_bits(block_group, data)) {
+                   u64 extra = BTRFS_BLOCK_GROUP_DUP |
+                               BTRFS_BLOCK_GROUP_RAID1 |
+                               BTRFS_BLOCK_GROUP_RAID10;
+
+                       /*
+                        * if they asked for extra copies and this block group
+                        * doesn't provide them, bail.  This does allow us to
+                        * fill raid0 from raid1.
+                        */
+                       if ((data & extra) && !(block_group->flags & extra))
+                               goto loop;
+               }
+
 have_block_group:
                if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
                        u64 free_percent;
 
-                       ret = cache_block_group(block_group, trans, 1);
+                       ret = cache_block_group(block_group, trans,
+                                               orig_root, 1);
                        if (block_group->cached == BTRFS_CACHE_FINISHED)
                                goto have_block_group;
 
@@ -4958,7 +4990,8 @@ have_block_group:
                        if (loop > LOOP_CACHING_NOWAIT ||
                            (loop > LOOP_FIND_IDEAL &&
                             atomic_read(&space_info->caching_threads) < 2)) {
-                               ret = cache_block_group(block_group, trans, 0);
+                               ret = cache_block_group(block_group, trans,
+                                                       orig_root, 0);
                                BUG_ON(ret);
                        }
                        found_uncached_bg = true;
@@ -5515,7 +5548,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
        u64 num_bytes = ins->offset;
 
        block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid);
-       cache_block_group(block_group, trans, 0);
+       cache_block_group(block_group, trans, NULL, 0);
        caching_ctl = get_caching_control(block_group);
 
        if (!caching_ctl) {
@@ -6300,9 +6333,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
                                           NULL, NULL);
                BUG_ON(ret < 0);
                if (ret > 0) {
-                       ret = btrfs_del_orphan_item(trans, tree_root,
-                                                   root->root_key.objectid);
-                       BUG_ON(ret);
+                       /* if we fail to delete the orphan item this time
+                        * around, it'll get picked up the next time.
+                        *
+                        * The most common failure here is just -ENOENT.
+                        */
+                       btrfs_del_orphan_item(trans, tree_root,
+                                             root->root_key.objectid);
                }
        }
 
@@ -7878,7 +7915,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags)
        u64 stripped = BTRFS_BLOCK_GROUP_RAID0 |
                BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10;
 
-       num_devices = root->fs_info->fs_devices->rw_devices;
+       /*
+        * we add in the count of missing devices because we want
+        * to make sure that any RAID levels on a degraded FS
+        * continue to be honored.
+        */
+       num_devices = root->fs_info->fs_devices->rw_devices +
+               root->fs_info->fs_devices->missing_devices;
+
        if (num_devices == 1) {
                stripped |= BTRFS_BLOCK_GROUP_DUP;
                stripped = flags & ~stripped;
@@ -8247,7 +8291,6 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                        break;
                if (ret != 0)
                        goto error;
-
                leaf = path->nodes[0];
                btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
                cache = kzalloc(sizeof(*cache), GFP_NOFS);
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..66836d85763bbfd2dafe3821a1be30f173784fdc 100644 (file)
@@ -48,30 +48,34 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
                                         struct page **prepared_pages,
                                         struct iov_iter *i)
 {
-       size_t copied;
+       size_t copied = 0;
        int pg = 0;
        int offset = pos & (PAGE_CACHE_SIZE - 1);
+       int total_copied = 0;
 
        while (write_bytes > 0) {
                size_t count = min_t(size_t,
                                     PAGE_CACHE_SIZE - offset, write_bytes);
                struct page *page = prepared_pages[pg];
-again:
-               if (unlikely(iov_iter_fault_in_readable(i, count)))
-                       return -EFAULT;
-
-               /* Copy data from userspace to the current page */
-               copied = iov_iter_copy_from_user(page, i, offset, count);
+               /*
+                * Copy data from userspace to the current page
+                *
+                * Disable pagefault to avoid recursive lock since
+                * the pages are already locked
+                */
+               pagefault_disable();
+               copied = iov_iter_copy_from_user_atomic(page, i, offset, count);
+               pagefault_enable();
 
                /* Flush processor's dcache for this page */
                flush_dcache_page(page);
                iov_iter_advance(i, copied);
                write_bytes -= copied;
+               total_copied += copied;
 
+               /* Return to btrfs_file_aio_write to fault page */
                if (unlikely(copied == 0)) {
-                       count = min_t(size_t, PAGE_CACHE_SIZE - offset,
-                                     iov_iter_single_seg_count(i));
-                       goto again;
+                       break;
                }
 
                if (unlikely(copied < PAGE_CACHE_SIZE - offset)) {
@@ -81,7 +85,7 @@ again:
                        offset = 0;
                }
        }
-       return 0;
+       return total_copied;
 }
 
 /*
@@ -854,6 +858,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
        unsigned long last_index;
        int will_write;
        int buffered = 0;
+       int copied = 0;
+       int dirty_pages = 0;
 
        will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) ||
                      (file->f_flags & O_DIRECT));
@@ -970,7 +976,17 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                WARN_ON(num_pages > nrptrs);
                memset(pages, 0, sizeof(struct page *) * nrptrs);
 
-               ret = btrfs_delalloc_reserve_space(inode, write_bytes);
+               /*
+                * Fault pages before locking them in prepare_pages
+                * to avoid recursive lock
+                */
+               if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+
+               ret = btrfs_delalloc_reserve_space(inode,
+                                       num_pages << PAGE_CACHE_SHIFT);
                if (ret)
                        goto out;
 
@@ -978,37 +994,49 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                                    pos, first_index, last_index,
                                    write_bytes);
                if (ret) {
-                       btrfs_delalloc_release_space(inode, write_bytes);
+                       btrfs_delalloc_release_space(inode,
+                                       num_pages << PAGE_CACHE_SHIFT);
                        goto out;
                }
 
-               ret = btrfs_copy_from_user(pos, num_pages,
+               copied = btrfs_copy_from_user(pos, num_pages,
                                           write_bytes, pages, &i);
-               if (ret == 0) {
+               dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >>
+                                       PAGE_CACHE_SHIFT;
+
+               if (num_pages > dirty_pages) {
+                       if (copied > 0)
+                               atomic_inc(
+                                       &BTRFS_I(inode)->outstanding_extents);
+                       btrfs_delalloc_release_space(inode,
+                                       (num_pages - dirty_pages) <<
+                                       PAGE_CACHE_SHIFT);
+               }
+
+               if (copied > 0) {
                        dirty_and_release_pages(NULL, root, file, pages,
-                                               num_pages, pos, write_bytes);
+                                               dirty_pages, pos, copied);
                }
 
                btrfs_drop_pages(pages, num_pages);
-               if (ret) {
-                       btrfs_delalloc_release_space(inode, write_bytes);
-                       goto out;
-               }
 
-               if (will_write) {
-                       filemap_fdatawrite_range(inode->i_mapping, pos,
-                                                pos + write_bytes - 1);
-               } else {
-                       balance_dirty_pages_ratelimited_nr(inode->i_mapping,
-                                                          num_pages);
-                       if (num_pages <
-                           (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
-                               btrfs_btree_balance_dirty(root, 1);
-                       btrfs_throttle(root);
+               if (copied > 0) {
+                       if (will_write) {
+                               filemap_fdatawrite_range(inode->i_mapping, pos,
+                                                        pos + copied - 1);
+                       } else {
+                               balance_dirty_pages_ratelimited_nr(
+                                                       inode->i_mapping,
+                                                       dirty_pages);
+                               if (dirty_pages <
+                               (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
+                                       btrfs_btree_balance_dirty(root, 1);
+                               btrfs_throttle(root);
+                       }
                }
 
-               pos += write_bytes;
-               num_written += write_bytes;
+               pos += copied;
+               num_written += copied;
 
                cond_resched();
        }
@@ -1047,8 +1075,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 +1101,7 @@ out:
                             (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT);
                }
        }
+done:
        current->backing_dev_info = NULL;
        return num_written ? num_written : err;
 }
index 22ee0dc2e6b8a712900c68a8c44df4a453fb86f0..60d684266959bbf8f96c14873e9a1f57e069a29e 100644 (file)
@@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
                       (unsigned long long)BTRFS_I(inode)->generation,
                       (unsigned long long)generation,
                       (unsigned long long)block_group->key.objectid);
-               goto out;
+               goto free_cache;
        }
 
        if (!num_entries)
@@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root,
                return 0;
        }
 
+       node = rb_first(&block_group->free_space_offset);
+       if (!node) {
+               iput(inode);
+               return 0;
+       }
+
        last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
        filemap_write_and_wait(inode->i_mapping);
        btrfs_wait_ordered_range(inode, inode->i_size &
@@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root,
         */
        first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64);
 
-       node = rb_first(&block_group->free_space_offset);
-       if (!node)
-               goto out_free;
-
        /*
         * Lock all pages first so we can lock the extent safely.
         *
index 558cac2dfa547032637bd0a746153eba46d73f8d..72f31ecb5c90085a2d6adfdc9b690ee038bf508f 100644 (file)
@@ -495,7 +495,7 @@ again:
                add_async_extent(async_cow, start, num_bytes,
                                 total_compressed, pages, nr_pages_ret);
 
-               if (start + num_bytes < end && start + num_bytes < actual_end) {
+               if (start + num_bytes < end) {
                        start += num_bytes;
                        pages = NULL;
                        cond_resched();
@@ -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 "
+                     "sector %#Lx len %u err no %d\n",
+                     dip->inode->i_ino, bio->bi_rw,
+                     (unsigned long long)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
@@ -5760,8 +5934,7 @@ free_ordered:
         */
        if (write) {
                struct btrfs_ordered_extent *ordered;
-               ordered = btrfs_lookup_ordered_extent(inode,
-                                                     dip->logical_offset);
+               ordered = btrfs_lookup_ordered_extent(inode, file_offset);
                if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) &&
                    !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags))
                        btrfs_free_reserved_extent(root, ordered->start,
@@ -6607,8 +6780,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 +6932,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 +6946,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 +7017,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 +7059,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 +7117,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 +7317,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..f87552a1d7ea0beeb540aa59ddac3754242304cc 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;
@@ -935,23 +947,42 @@ out:
 
 static noinline int btrfs_ioctl_snap_create(struct file *file,
                                            void __user *arg, int subvol,
-                                           int async)
+                                           int v2)
 {
        struct btrfs_ioctl_vol_args *vol_args = NULL;
-       struct btrfs_ioctl_async_vol_args *async_vol_args = NULL;
+       struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL;
        char *name;
        u64 fd;
-       u64 transid = 0;
        int ret;
 
-       if (async) {
-               async_vol_args = memdup_user(arg, sizeof(*async_vol_args));
-               if (IS_ERR(async_vol_args))
-                       return PTR_ERR(async_vol_args);
+       if (v2) {
+               u64 transid = 0;
+               u64 *ptr = NULL;
+
+               vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2));
+               if (IS_ERR(vol_args_v2))
+                       return PTR_ERR(vol_args_v2);
+
+               if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               name = vol_args_v2->name;
+               fd = vol_args_v2->fd;
+               vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
+
+               if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC)
+                       ptr = &transid;
+
+               ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+                                                     subvol, ptr);
 
-               name = async_vol_args->name;
-               fd = async_vol_args->fd;
-               async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0';
+               if (ret == 0 && ptr &&
+                   copy_to_user(arg +
+                                offsetof(struct btrfs_ioctl_vol_args_v2,
+                                         transid), ptr, sizeof(*ptr)))
+                       ret = -EFAULT;
        } else {
                vol_args = memdup_user(arg, sizeof(*vol_args));
                if (IS_ERR(vol_args))
@@ -959,20 +990,13 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
                name = vol_args->name;
                fd = vol_args->fd;
                vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
-       }
-
-       ret = btrfs_ioctl_snap_create_transid(file, name, fd,
-                                             subvol, &transid);
 
-       if (!ret && async) {
-               if (copy_to_user(arg +
-                               offsetof(struct btrfs_ioctl_async_vol_args,
-                               transid), &transid, sizeof(transid)))
-                       return -EFAULT;
+               ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+                                                     subvol, NULL);
        }
-
+out:
        kfree(vol_args);
-       kfree(async_vol_args);
+       kfree(vol_args_v2);
 
        return ret;
 }
@@ -1669,12 +1693,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 +1897,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);
 
@@ -2235,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int
                return btrfs_ioctl_getversion(file, argp);
        case BTRFS_IOC_SNAP_CREATE:
                return btrfs_ioctl_snap_create(file, argp, 0, 0);
-       case BTRFS_IOC_SNAP_CREATE_ASYNC:
+       case BTRFS_IOC_SNAP_CREATE_V2:
                return btrfs_ioctl_snap_create(file, argp, 0, 1);
        case BTRFS_IOC_SUBVOL_CREATE:
                return btrfs_ioctl_snap_create(file, argp, 1, 0);
index 17c99ebdf96049a8ad028cd6e138355df86f0c9e..c344d12c646bf7d1cbb953f8c4aba6257b6db8b9 100644 (file)
@@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args {
        char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
-#define BTRFS_SNAPSHOT_NAME_MAX 4079
-struct btrfs_ioctl_async_vol_args {
+#define BTRFS_SUBVOL_CREATE_ASYNC      (1ULL << 0)
+
+#define BTRFS_SUBVOL_NAME_MAX 4039
+struct btrfs_ioctl_vol_args_v2 {
        __s64 fd;
        __u64 transid;
-       char name[BTRFS_SNAPSHOT_NAME_MAX + 1];
+       __u64 flags;
+       __u64 unused[4];
+       char name[BTRFS_SUBVOL_NAME_MAX + 1];
 };
 
 #define BTRFS_INO_LOOKUP_PATH_MAX 4080
@@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args {
                                    struct btrfs_ioctl_space_args)
 #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
 #define BTRFS_IOC_WAIT_SYNC  _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
-#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \
-                                  struct btrfs_ioctl_async_vol_args)
+#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
+                                  struct btrfs_ioctl_vol_args_v2)
 #endif
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 79cba5fbc28ef8061e2d599110a3a525216a7bfd..f8be250963a09a283b8ec4ab04bcb1c3a962427e 100644 (file)
@@ -56,8 +56,12 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans,
                return -ENOMEM;
 
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
-       if (ret)
+       if (ret < 0)
                goto out;
+       if (ret) {
+               ret = -ENOENT;
+               goto out;
+       }
 
        ret = btrfs_del_item(trans, root, path);
 
index 8299a25ffc8f8313064cbd3e54278e9f5ebbc662..883c6fa1367eb866002d7f67d3ae2ce6497f4367 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;
 
@@ -652,9 +685,9 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
                mutex_unlock(&root->d_inode->i_mutex);
 
                if (IS_ERR(new_root)) {
+                       dput(root);
                        deactivate_locked_super(s);
                        error = PTR_ERR(new_root);
-                       dput(root);
                        goto error_free_subvol_name;
                }
                if (!new_root->d_inode) {
@@ -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 95324e9f928013e5943108948d654b0d9aa298d1..1718e1a5c3208b154503edb278accf6e91449c55 100644 (file)
@@ -412,12 +412,16 @@ static noinline int device_list_add(const char *path,
 
                device->fs_devices = fs_devices;
                fs_devices->num_devices++;
-       } else if (strcmp(device->name, path)) {
+       } else if (!device->name || strcmp(device->name, path)) {
                name = kstrdup(path, GFP_NOFS);
                if (!name)
                        return -ENOMEM;
                kfree(device->name);
                device->name = name;
+               if (device->missing) {
+                       fs_devices->missing_devices--;
+                       device->missing = 0;
+               }
        }
 
        if (found_transid > fs_devices->latest_trans) {
@@ -1239,6 +1243,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 
        device->fs_devices->num_devices--;
 
+       if (device->missing)
+               root->fs_info->fs_devices->missing_devices--;
+
        next_device = list_entry(root->fs_info->fs_devices->devices.next,
                                 struct btrfs_device, dev_list);
        if (device->bdev == root->fs_info->sb->s_bdev)
@@ -3084,7 +3091,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root,
        device->devid = devid;
        device->work.func = pending_bios_fn;
        device->fs_devices = fs_devices;
+       device->missing = 1;
        fs_devices->num_devices++;
+       fs_devices->missing_devices++;
        spin_lock_init(&device->io_lock);
        INIT_LIST_HEAD(&device->dev_alloc_list);
        memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE);
@@ -3282,6 +3291,15 @@ static int read_one_dev(struct btrfs_root *root,
                        device = add_missing_dev(root, devid, dev_uuid);
                        if (!device)
                                return -ENOMEM;
+               } else if (!device->missing) {
+                       /*
+                        * this happens when a device that was properly setup
+                        * in the device info lists suddenly goes bad.
+                        * device->bdev is NULL, and so we have to set
+                        * device->missing to one here
+                        */
+                       root->fs_info->fs_devices->missing_devices++;
+                       device->missing = 1;
                }
        }
 
index 856e7577030467c19d8930f172179e9e6920eac3..1be7810794500b2b8d5ef6697e1749a93303ce40 100644 (file)
@@ -44,6 +44,7 @@ struct btrfs_device {
 
        int writeable;
        int in_fs_metadata;
+       int missing;
 
        spinlock_t io_lock;
 
@@ -93,6 +94,7 @@ struct btrfs_fs_devices {
        u64 num_devices;
        u64 open_devices;
        u64 rw_devices;
+       u64 missing_devices;
        u64 total_rw_bytes;
        struct block_device *latest_bdev;
 
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..158c700fdca5e4f62763377a8374217d6371b68b 100644 (file)
@@ -114,8 +114,8 @@ static int __dcache_readdir(struct file *filp,
        spin_lock(&dcache_lock);
 
        /* start at beginning? */
-       if (filp->f_pos == 2 || (last &&
-                                filp->f_pos < ceph_dentry(last)->offset)) {
+       if (filp->f_pos == 2 || last == NULL ||
+           filp->f_pos < ceph_dentry(last)->offset) {
                if (list_empty(&parent->d_subdirs))
                        goto out_unlock;
                p = parent->d_subdirs.prev;
@@ -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 a6ce54e94eb5ab435670093cd6ad789e72cc627b..52e8fd74d450b9e2895eb7c29d80e38b77eb0807 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/ioctl.h>
 #include <linux/types.h>
 
-#define CEPH_IOCTL_MAGIC 0x98
+#define CEPH_IOCTL_MAGIC 0x97
 
 /* just use u64 to align sanely on all archs */
 struct ceph_ioctl_layout {
index 40abde93c345d054279fd51cbca998525c4931c7..476b329867d41cf2cec7b3e2ad51e5f3885d9d7a 100644 (file)
  * Implement fcntl and flock locking functions.
  */
 static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
-                            u64 pid, u64 pid_ns,
-                            int cmd, u64 start, u64 length, u8 wait)
+                            int cmd, u8 wait, struct file_lock *fl)
 {
        struct inode *inode = file->f_dentry->d_inode;
        struct ceph_mds_client *mdsc =
                ceph_sb_to_client(inode->i_sb)->mdsc;
        struct ceph_mds_request *req;
        int err;
+       u64 length = 0;
 
        req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
        if (IS_ERR(req))
                return PTR_ERR(req);
        req->r_inode = igrab(inode);
 
+       /* mds requires start and length rather than start and end */
+       if (LLONG_MAX == fl->fl_end)
+               length = 0;
+       else
+               length = fl->fl_end - fl->fl_start + 1;
+
        dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
             "length: %llu, wait: %d, type`: %d", (int)lock_type,
-            (int)operation, pid, start, length, wait, cmd);
+            (int)operation, (u64)fl->fl_pid, fl->fl_start,
+            length, wait, fl->fl_type);
+
 
        req->r_args.filelock_change.rule = lock_type;
        req->r_args.filelock_change.type = cmd;
-       req->r_args.filelock_change.pid = cpu_to_le64(pid);
+       req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
        /* This should be adjusted, but I'm not sure if
           namespaces actually get id numbers*/
        req->r_args.filelock_change.pid_namespace =
-               cpu_to_le64((u64)pid_ns);
-       req->r_args.filelock_change.start = cpu_to_le64(start);
+               cpu_to_le64((u64)(unsigned long)fl->fl_nspid);
+       req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start);
        req->r_args.filelock_change.length = cpu_to_le64(length);
        req->r_args.filelock_change.wait = wait;
 
        err = ceph_mdsc_do_request(mdsc, inode, req);
+
+       if ( operation == CEPH_MDS_OP_GETFILELOCK){
+               fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid);
+               if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
+                       fl->fl_type = F_RDLCK;
+               else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type)
+                       fl->fl_type = F_WRLCK;
+               else
+                       fl->fl_type = F_UNLCK;
+
+               fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start);
+               length = le64_to_cpu(req->r_reply_info.filelock_reply->start) +
+                                                le64_to_cpu(req->r_reply_info.filelock_reply->length);
+               if (length >= 1)
+                       fl->fl_end = length -1;
+               else
+                       fl->fl_end = 0;
+
+       }
        ceph_mdsc_put_request(req);
        dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
-            "length: %llu, wait: %d, type`: %d err code %d", (int)lock_type,
-            (int)operation, pid, start, length, wait, cmd, err);
+            "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type,
+            (int)operation, (u64)fl->fl_pid, fl->fl_start,
+            length, wait, fl->fl_type, err);
        return err;
 }
 
@@ -54,7 +82,6 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
  */
 int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
 {
-       u64 length;
        u8 lock_cmd;
        int err;
        u8 wait = 0;
@@ -76,29 +103,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
        else
                lock_cmd = CEPH_LOCK_UNLOCK;
 
-       if (LLONG_MAX == fl->fl_end)
-               length = 0;
-       else
-               length = fl->fl_end - fl->fl_start + 1;
-
-       err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
-                               (u64)fl->fl_pid,
-                               (u64)(unsigned long)fl->fl_nspid,
-                               lock_cmd, fl->fl_start,
-                               length, wait);
+       err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl);
        if (!err) {
-               dout("mds locked, locking locally");
-               err = posix_lock_file(file, fl, NULL);
-               if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
-                       /* undo! This should only happen if the kernel detects
-                        * local deadlock. */
-                       ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
-                                         (u64)fl->fl_pid,
-                                         (u64)(unsigned long)fl->fl_nspid,
-                                         CEPH_LOCK_UNLOCK, fl->fl_start,
-                                         length, 0);
-                       dout("got %d on posix_lock_file, undid lock", err);
+               if ( op != CEPH_MDS_OP_GETFILELOCK ){
+                       dout("mds locked, locking locally");
+                       err = posix_lock_file(file, fl, NULL);
+                       if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
+                               /* undo! This should only happen if the kernel detects
+                                * local deadlock. */
+                               ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
+                                                 CEPH_LOCK_UNLOCK, 0, fl);
+                               dout("got %d on posix_lock_file, undid lock", err);
+                       }
                }
+
        } else {
                dout("mds returned error code %d", err);
        }
@@ -107,7 +125,6 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
 
 int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
 {
-       u64 length;
        u8 lock_cmd;
        int err;
        u8 wait = 1;
@@ -127,26 +144,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
                lock_cmd = CEPH_LOCK_EXCL;
        else
                lock_cmd = CEPH_LOCK_UNLOCK;
-       /* mds requires start and length rather than start and end */
-       if (LLONG_MAX == fl->fl_end)
-               length = 0;
-       else
-               length = fl->fl_end - fl->fl_start + 1;
 
        err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
-                               file, (u64)fl->fl_pid,
-                               (u64)(unsigned long)fl->fl_nspid,
-                               lock_cmd, fl->fl_start,
-                               length, wait);
+                               file, lock_cmd, wait, fl);
        if (!err) {
                err = flock_lock_file_wait(file, fl);
                if (err) {
                        ceph_lock_message(CEPH_LOCK_FLOCK,
                                          CEPH_MDS_OP_SETFILELOCK,
-                                         file, (u64)fl->fl_pid,
-                                         (u64)(unsigned long)fl->fl_nspid,
-                                         CEPH_LOCK_UNLOCK, fl->fl_start,
-                                         length, 0);
+                                         file, CEPH_LOCK_UNLOCK, 0, fl);
                        dout("got %d on flock_lock_file_wait, undid lock", err);
                }
        } else {
index 3142b15940c25656a43ec3a5d72af3e1ee1cece9..38800eaa81d066bd8f06a401d082ecd3bb3f6fea 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"
@@ -202,6 +201,38 @@ out_bad:
        return err;
 }
 
+/*
+ * parse fcntl F_GETLK results
+ */
+static int parse_reply_info_filelock(void **p, void *end,
+                struct ceph_mds_reply_info_parsed *info)
+{
+       if (*p + sizeof(*info->filelock_reply) > end)
+               goto bad;
+
+       info->filelock_reply = *p;
+       *p += sizeof(*info->filelock_reply);
+
+       if (unlikely(*p != end))
+               goto bad;
+       return 0;
+
+bad:
+       return -EIO;
+}
+
+/*
+ * parse extra results
+ */
+static int parse_reply_info_extra(void **p, void *end,
+                struct ceph_mds_reply_info_parsed *info)
+{
+       if (info->head->op == CEPH_MDS_OP_GETFILELOCK)
+               return parse_reply_info_filelock(p, end, info);
+       else
+               return parse_reply_info_dir(p, end, info);
+}
+
 /*
  * parse entire mds reply
  */
@@ -224,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg,
                        goto out_bad;
        }
 
-       /* dir content */
+       /* extra */
        ceph_decode_32_safe(&p, end, len, bad);
        if (len > 0) {
-               err = parse_reply_info_dir(&p, p+len, info);
+               err = parse_reply_info_extra(&p, p+len, info);
                if (err < 0)
                        goto out_bad;
        }
@@ -529,6 +560,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 +1622,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);
@@ -2072,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
 
        mutex_lock(&session->s_mutex);
        if (err < 0) {
-               pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds);
+               pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid);
                ceph_msg_dump(msg);
                goto out_err;
        }
@@ -2092,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
        mutex_lock(&req->r_fill_mutex);
        err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
        if (err == 0) {
-               if (result == 0 && rinfo->dir_nr)
+               if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK &&
+                   rinfo->dir_nr)
                        ceph_readdir_prepopulate(req, req->r_session);
                ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
        }
index d66d63c7235526ef63d16ff0ea1e9ba3899df586..aabe563b54db308af80ee9fff18dd81610a9cf94 100644 (file)
@@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in {
 };
 
 /*
- * parsed info about an mds reply, including information about the
- * target inode and/or its parent directory and dentry, and directory
- * contents (for readdir results).
+ * parsed info about an mds reply, including information about
+ * either: 1) the target inode and/or its parent directory and dentry,
+ * and directory contents (for readdir results), or
+ * 2) the file range lock info (for fcntl F_GETLK results).
  */
 struct ceph_mds_reply_info_parsed {
        struct ceph_mds_reply_head    *head;
 
+       /* trace */
        struct ceph_mds_reply_info_in diri, targeti;
        struct ceph_mds_reply_dirfrag *dirfrag;
        char                          *dname;
        u32                           dname_len;
        struct ceph_mds_reply_lease   *dlease;
 
-       struct ceph_mds_reply_dirfrag *dir_dir;
-       int                           dir_nr;
-       char                          **dir_dname;
-       u32                           *dir_dname_len;
-       struct ceph_mds_reply_lease   **dir_dlease;
-       struct ceph_mds_reply_info_in *dir_in;
-       u8                            dir_complete, dir_end;
+       /* extra */
+       union {
+               /* for fcntl F_GETLK results */
+               struct ceph_filelock *filelock_reply;
+
+               /* for readdir results */
+               struct {
+                       struct ceph_mds_reply_dirfrag *dir_dir;
+                       int                           dir_nr;
+                       char                          **dir_dname;
+                       u32                           *dir_dname_len;
+                       struct ceph_mds_reply_lease   **dir_dlease;
+                       struct ceph_mds_reply_info_in *dir_in;
+                       u8                            dir_complete, dir_end;
+               };
+       };
 
        /* encoded blob describing snapshot contexts for certain
           operations (e.g., open) */
@@ -170,6 +181,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 adefa60a9bdc10108ec9c802e4cbe1ea26f3f6e0..43b19dd391912476c395ffbabaaabbacc28d0146 100644 (file)
@@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o
 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
          link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
          md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
-         readdir.o ioctl.o sess.o export.o cifsacl.o
+         readdir.o ioctl.o sess.o export.o
+
+cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
 
 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
 
index ee68d1036544d591930af8119d5e7450634adfff..46af99ab3614d545675e41e788686b39fd51204b 100644 (file)
@@ -337,6 +337,15 @@ A partial list of the supported mount options follows:
   wsize                default write size (default 57344)
                maximum wsize currently allowed by CIFS is 57344 (fourteen
                4096 byte pages)
+  actimeo=n    attribute cache timeout in seconds (default 1 second).
+               After this timeout, the cifs client requests fresh attribute
+               information from the server. This option allows to tune the
+               attribute cache timeout to suit the workload needs. Shorter
+               timeouts mean better the cache coherency, but increased number
+               of calls to the server. Longer timeouts mean reduced number
+               of calls to the server at the expense of less stricter cache
+               coherency checks (i.e. incorrect attribute cache for a short
+               period of time).
   rw           mount the network share read-write (note that the
                server may still consider the share read-only)
   ro           mount network share read-only
index e9a393c9c2ca4ddb8ec3d75cfcf0766234ec1789..7852cd6770517a8a5da7877fb788a834a0534c86 100644 (file)
@@ -48,6 +48,7 @@ struct cifs_sb_info {
        struct nls_table *local_nls;
        unsigned int rsize;
        unsigned int wsize;
+       unsigned long actimeo; /* attribute cache timeout (jiffies) */
        atomic_t active;
        uid_t   mnt_uid;
        gid_t   mnt_gid;
index c9b4792ae82538761b056ffba55173e77a2f2c8c..a437ec391a015fb7c05725543d6c118eadefc466 100644 (file)
@@ -30,8 +30,6 @@
 #include "cifs_debug.h"
 
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
 static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
        {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
        {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
@@ -560,7 +558,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 +566,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 +583,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 +591,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 +694,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 +710,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 +739,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 */
@@ -766,4 +772,3 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
 
        return rc;
 }
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
index 6c8096cf51557764aa10af6c28d108d3e93ce6e7..c4ae7d0365631f5d01db610ef3153502f2531c9d 100644 (file)
@@ -74,11 +74,7 @@ struct cifs_wksid {
        char sidname[SIDNAMELENGTH];
 } __attribute__((packed));
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
 extern int match_sid(struct cifs_sid *);
 extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
 
-#endif /*  CONFIG_CIFS_EXPERIMENTAL */
-
 #endif /* _CIFSACL_H */
index 9c3789762ab7c4c92a7d67859c34b32cb196f1ab..3936aa7f2c2285cfb59857f8fe1925528920543a 100644 (file)
@@ -458,9 +458,13 @@ 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);
+       /* convert actimeo and display it in seconds */
+               seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
 
        return 0;
 }
@@ -933,7 +937,6 @@ init_cifs(void)
        GlobalCurrentXid = 0;
        GlobalTotalActiveXid = 0;
        GlobalMaxActiveXid = 0;
-       memset(Local_System_Name, 0, 15);
        spin_lock_init(&cifs_tcp_ses_lock);
        spin_lock_init(&cifs_file_list_lock);
        spin_lock_init(&GlobalMid_Lock);
index b577bf0a1bb3622491ed0a885ca30b9e7684d24e..7136c0c3e2f961ec2c57d882163a1ffbc0e50ef1 100644 (file)
 
 #define CIFS_MIN_RCV_POOL 4
 
+/*
+ * default attribute cache timeout (jiffies)
+ */
+#define CIFS_DEF_ACTIMEO (1 * HZ)
+
+/*
+ * max attribute cache timeout (jiffies) - 2^30
+ */
+#define CIFS_MAX_ACTIMEO (1 << 30)
+
 /*
  * MAX_REQ is the maximum number of requests that WE will send
  * on one socket concurrently. It also matches the most common
@@ -746,8 +756,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
 GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
 GLOBAL_EXTERN spinlock_t GlobalMid_Lock;  /* protects above & list operations */
                                          /* on midQ entries */
-GLOBAL_EXTERN char Local_System_Name[15];
-
 /*
  *  Global counters, updated atomically
  */
index 7ed69b6b5fe6719f66ed5af0a0b38d2cda1aa352..e6d1481b16c1403cbe1c7fcae04e11abcc3f91f9 100644 (file)
@@ -54,7 +54,8 @@ do {                                                          \
             __func__, curr_xid, (int)rc);                      \
 } while (0)
 extern char *build_path_from_dentry(struct dentry *);
-extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb);
+extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+                                       struct cifsTconInfo *tcon);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 extern char *cifs_compose_mount_options(const char *sb_mountdata,
                const char *fullpath, const struct dfs_info3_param *ref,
@@ -79,9 +80,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb,
                                  struct TCP_Server_Info *);
 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
-#endif
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
@@ -130,10 +129,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 2f2632b6df5a1efd960bf44502d280e0e9499908..67acfb3acad271a51be1a1446d4f9828119e6b39 100644 (file)
@@ -2478,95 +2478,6 @@ querySymLinkRetry:
 }
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
-/* Initialize NT TRANSACT SMB into small smb request buffer.
-   This assumes that all NT TRANSACTS that we init here have
-   total parm and data under about 400 bytes (to fit in small cifs
-   buffer size), which is the case so far, it easily fits. NB:
-       Setup words themselves and ByteCount
-       MaxSetupCount (size of returned setup area) and
-       MaxParameterCount (returned parms size) must be set by caller */
-static int
-smb_init_nttransact(const __u16 sub_command, const int setup_count,
-                  const int parm_len, struct cifsTconInfo *tcon,
-                  void **ret_buf)
-{
-       int rc;
-       __u32 temp_offset;
-       struct smb_com_ntransact_req *pSMB;
-
-       rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
-                               (void **)&pSMB);
-       if (rc)
-               return rc;
-       *ret_buf = (void *)pSMB;
-       pSMB->Reserved = 0;
-       pSMB->TotalParameterCount = cpu_to_le32(parm_len);
-       pSMB->TotalDataCount  = 0;
-       pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
-                                         MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
-       pSMB->ParameterCount = pSMB->TotalParameterCount;
-       pSMB->DataCount  = pSMB->TotalDataCount;
-       temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
-                       (setup_count * 2) - 4 /* for rfc1001 length itself */;
-       pSMB->ParameterOffset = cpu_to_le32(temp_offset);
-       pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
-       pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
-       pSMB->SubCommand = cpu_to_le16(sub_command);
-       return 0;
-}
-
-static int
-validate_ntransact(char *buf, char **ppparm, char **ppdata,
-                  __u32 *pparmlen, __u32 *pdatalen)
-{
-       char *end_of_smb;
-       __u32 data_count, data_offset, parm_count, parm_offset;
-       struct smb_com_ntransact_rsp *pSMBr;
-
-       *pdatalen = 0;
-       *pparmlen = 0;
-
-       if (buf == NULL)
-               return -EINVAL;
-
-       pSMBr = (struct smb_com_ntransact_rsp *)buf;
-
-       /* ByteCount was converted from little endian in SendReceive */
-       end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
-                       (char *)&pSMBr->ByteCount;
-
-       data_offset = le32_to_cpu(pSMBr->DataOffset);
-       data_count = le32_to_cpu(pSMBr->DataCount);
-       parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
-       parm_count = le32_to_cpu(pSMBr->ParameterCount);
-
-       *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
-       *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
-
-       /* should we also check that parm and data areas do not overlap? */
-       if (*ppparm > end_of_smb) {
-               cFYI(1, "parms start after end of smb");
-               return -EINVAL;
-       } else if (parm_count + *ppparm > end_of_smb) {
-               cFYI(1, "parm end after end of smb");
-               return -EINVAL;
-       } else if (*ppdata > end_of_smb) {
-               cFYI(1, "data starts after end of smb");
-               return -EINVAL;
-       } else if (data_count + *ppdata > end_of_smb) {
-               cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
-                       *ppdata, data_count, (data_count + *ppdata),
-                       end_of_smb, pSMBr);
-               return -EINVAL;
-       } else if (parm_count + data_count > pSMBr->ByteCount) {
-               cFYI(1, "parm count and data count larger than SMB");
-               return -EINVAL;
-       }
-       *pdatalen = data_count;
-       *pparmlen = parm_count;
-       return 0;
-}
-
 int
 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                        const unsigned char *searchName,
@@ -3056,7 +2967,97 @@ GetExtAttrOut:
 
 #endif /* CONFIG_POSIX */
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
+/*
+ * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
+ * all NT TRANSACTS that we init here have total parm and data under about 400
+ * bytes (to fit in small cifs buffer size), which is the case so far, it
+ * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
+ * returned setup area) and MaxParameterCount (returned parms size) must be set
+ * by caller
+ */
+static int
+smb_init_nttransact(const __u16 sub_command, const int setup_count,
+                  const int parm_len, struct cifsTconInfo *tcon,
+                  void **ret_buf)
+{
+       int rc;
+       __u32 temp_offset;
+       struct smb_com_ntransact_req *pSMB;
+
+       rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
+                               (void **)&pSMB);
+       if (rc)
+               return rc;
+       *ret_buf = (void *)pSMB;
+       pSMB->Reserved = 0;
+       pSMB->TotalParameterCount = cpu_to_le32(parm_len);
+       pSMB->TotalDataCount  = 0;
+       pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+                                         MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
+       pSMB->ParameterCount = pSMB->TotalParameterCount;
+       pSMB->DataCount  = pSMB->TotalDataCount;
+       temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
+                       (setup_count * 2) - 4 /* for rfc1001 length itself */;
+       pSMB->ParameterOffset = cpu_to_le32(temp_offset);
+       pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
+       pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
+       pSMB->SubCommand = cpu_to_le16(sub_command);
+       return 0;
+}
+
+static int
+validate_ntransact(char *buf, char **ppparm, char **ppdata,
+                  __u32 *pparmlen, __u32 *pdatalen)
+{
+       char *end_of_smb;
+       __u32 data_count, data_offset, parm_count, parm_offset;
+       struct smb_com_ntransact_rsp *pSMBr;
+
+       *pdatalen = 0;
+       *pparmlen = 0;
+
+       if (buf == NULL)
+               return -EINVAL;
+
+       pSMBr = (struct smb_com_ntransact_rsp *)buf;
+
+       /* ByteCount was converted from little endian in SendReceive */
+       end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
+                       (char *)&pSMBr->ByteCount;
+
+       data_offset = le32_to_cpu(pSMBr->DataOffset);
+       data_count = le32_to_cpu(pSMBr->DataCount);
+       parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
+       parm_count = le32_to_cpu(pSMBr->ParameterCount);
+
+       *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
+       *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
+
+       /* should we also check that parm and data areas do not overlap? */
+       if (*ppparm > end_of_smb) {
+               cFYI(1, "parms start after end of smb");
+               return -EINVAL;
+       } else if (parm_count + *ppparm > end_of_smb) {
+               cFYI(1, "parm end after end of smb");
+               return -EINVAL;
+       } else if (*ppdata > end_of_smb) {
+               cFYI(1, "data starts after end of smb");
+               return -EINVAL;
+       } else if (data_count + *ppdata > end_of_smb) {
+               cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
+                       *ppdata, data_count, (data_count + *ppdata),
+                       end_of_smb, pSMBr);
+               return -EINVAL;
+       } else if (parm_count + data_count > pSMBr->ByteCount) {
+               cFYI(1, "parm count and data count larger than SMB");
+               return -EINVAL;
+       }
+       *pdatalen = data_count;
+       *pparmlen = parm_count;
+       return 0;
+}
+
 /* Get Security Descriptor (by handle) from remote server for a file or dir */
 int
 CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
@@ -3214,7 +3215,7 @@ setCifsAclRetry:
        return (rc);
 }
 
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
+#endif /* CONFIG_CIFS_ACL */
 
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */
index 251a17c03545dfc35e8ab37e1ea5a612e94f7536..cc1a8604a790b46767e066a59ef897f314144163 100644 (file)
@@ -105,6 +105,7 @@ struct smb_vol {
        unsigned int wsize;
        bool sockopt_tcp_nodelay:1;
        unsigned short int port;
+       unsigned long actimeo; /* attribute cache timeout (jiffies) */
        char *prepath;
        struct sockaddr_storage srcaddr; /* allow binding to a local IP */
        struct nls_table *local_nls;
@@ -806,23 +807,20 @@ cifs_parse_mount_options(char *options, const char *devname,
        short int override_gid = -1;
        bool uid_specified = false;
        bool gid_specified = false;
+       char *nodename = utsname()->nodename;
 
        separator[0] = ',';
        separator[1] = 0;
 
-       if (Local_System_Name[0] != 0)
-               memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
-       else {
-               char *nodename = utsname()->nodename;
-               int n = strnlen(nodename, 15);
-               memset(vol->source_rfc1001_name, 0x20, 15);
-               for (i = 0; i < n; i++) {
-                       /* does not have to be perfect mapping since field is
-                       informational, only used for servers that do not support
-                       port 445 and it can be overridden at mount time */
-                       vol->source_rfc1001_name[i] = toupper(nodename[i]);
-               }
-       }
+       /*
+        * does not have to be perfect mapping since field is
+        * informational, only used for servers that do not support
+        * port 445 and it can be overridden at mount time
+        */
+       memset(vol->source_rfc1001_name, 0x20, 15);
+       for (i = 0; i < strnlen(nodename, 15); i++)
+               vol->source_rfc1001_name[i] = toupper(nodename[i]);
+
        vol->source_rfc1001_name[15] = 0;
        /* null target name indicates to use *SMBSERVR default called name
           if we end up sending RFC1001 session initialize */
@@ -840,6 +838,8 @@ cifs_parse_mount_options(char *options, const char *devname,
        /* default to using server inode numbers where available */
        vol->server_ino = 1;
 
+       vol->actimeo = CIFS_DEF_ACTIMEO;
+
        if (!options)
                return 1;
 
@@ -1214,6 +1214,16 @@ cifs_parse_mount_options(char *options, const char *devname,
                                        printk(KERN_WARNING "CIFS: server net"
                                        "biosname longer than 15 truncated.\n");
                        }
+               } else if (strnicmp(data, "actimeo", 7) == 0) {
+                       if (value && *value) {
+                               vol->actimeo = HZ * simple_strtoul(value,
+                                                                  &value, 0);
+                               if (vol->actimeo > CIFS_MAX_ACTIMEO) {
+                                       cERROR(1, "CIFS: attribute cache"
+                                                       "timeout too large");
+                                       return 1;
+                               }
+                       }
                } else if (strnicmp(data, "credentials", 4) == 0) {
                        /* ignore */
                } else if (strnicmp(data, "version", 3) == 0) {
@@ -1352,6 +1362,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;
@@ -2566,6 +2581,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        cFYI(1, "file mode: 0x%x  dir mode: 0x%x",
                cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
 
+       cifs_sb->actimeo = pvolume_info->actimeo;
+
        if (pvolume_info->noperm)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
        if (pvolume_info->setuids)
@@ -2816,13 +2833,13 @@ remote_path_check:
        /* check if a whole path (including prepath) is not remote */
        if (!rc && cifs_sb->prepathlen && tcon) {
                /* build_path_to_root works only when we have a valid tcon */
-               full_path = cifs_build_path_to_root(cifs_sb);
+               full_path = cifs_build_path_to_root(cifs_sb, tcon);
                if (full_path == NULL) {
                        rc = -ENOMEM;
                        goto mount_fail_check;
                }
                rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
-               if (rc != -EREMOTE) {
+               if (rc != 0 && rc != -EREMOTE) {
                        kfree(full_path);
                        goto mount_fail_check;
                }
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..5a28660ca2b5e619955c05d74d9d84b95a994a4b 100644 (file)
@@ -1108,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
        return total_written;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
                                        bool fsuid_only)
 {
@@ -1142,7 +1141,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
        spin_unlock(&cifs_file_list_lock);
        return NULL;
 }
-#endif
 
 struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
                                        bool fsuid_only)
@@ -2271,8 +2269,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..589f3e3f6e0023b1f8b09f1e030119896117c94f 100644 (file)
@@ -686,13 +686,18 @@ int cifs_get_inode_info(struct inode **pinode,
                        cFYI(1, "cifs_sfu_type failed: %d", tmprc);
        }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
        /* 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
+#endif /* CONFIG_CIFS_ACL */
 
        /* fill in remaining high mode bits e.g. SUID, VTX */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
@@ -723,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = {
        .lookup = cifs_lookup,
 };
 
-char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
+char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+                               struct cifsTconInfo *tcon)
 {
        int pplen = cifs_sb->prepathlen;
        int dfsplen;
        char *full_path = NULL;
-       struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
        /* if no prefix path, simply set path to the root of share to "" */
        if (pplen == 0) {
@@ -870,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
        char *full_path;
        struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
-       full_path = cifs_build_path_to_root(cifs_sb);
+       full_path = cifs_build_path_to_root(cifs_sb, tcon);
        if (full_path == NULL)
                return ERR_PTR(-ENOMEM);
 
@@ -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
@@ -1648,6 +1653,7 @@ static bool
 cifs_inode_needs_reval(struct inode *inode)
 {
        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 
        if (cifs_i->clientCanCacheRead)
                return false;
@@ -1658,19 +1664,21 @@ cifs_inode_needs_reval(struct inode *inode)
        if (cifs_i->time == 0)
                return true;
 
-       /* FIXME: the actimeo should be tunable */
-       if (time_after_eq(jiffies, cifs_i->time + HZ))
+       if (!time_in_range(jiffies, cifs_i->time,
+                               cifs_i->time + cifs_sb->actimeo))
                return true;
 
        /* hardlinked files w/ noserverino get "special" treatment */
-       if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
            S_ISREG(inode->i_mode) && inode->i_nlink != 1)
                return true;
 
        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)
 {
@@ -2114,11 +2122,16 @@ 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
-#endif
+#ifdef CONFIG_CIFS_ACL
+               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 /* CONFIG_CIFS_ACL */
                if (((mode & S_IWUGO) == 0) &&
                    (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
 
index ef7bb7b50f58e679ffabb8b8dad65420efb81271..a73eb9f4bdaf3608c2bf6f5dc124b5fabdd4445b 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) {
@@ -756,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
        rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
                     ino, fattr.cf_dtype);
 
-       /*
-        * we can not return filldir errors to the caller since they are
-        * "normal" when the stat blocksize is too small - we return remapped
-        * error instead
-        *
-        * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above
-        * case already. Why should we be clobbering other errors from it?
-        */
-       if (rc) {
-               cFYI(1, "filldir rc = %d", rc);
-               rc = -EOVERFLOW;
-       }
        dput(tmp_dentry);
        return rc;
 }
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..c62efcb959c73fc458367d811c576e634fb49634 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
@@ -254,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
        vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
        INIT_LIST_HEAD(&vma->anon_vma_chain);
+
+       err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+       if (err)
+               goto err;
+
        err = insert_vm_struct(mm, vma);
        if (err)
                goto err;
@@ -276,7 +302,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 +1033,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 +1457,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 123720ba786d7dd683ded8f5189d3261af7c7992..0fad7c0449fb632cd3285e12ce7e17e30e446c64 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 6a5edea2d70b3ac7c56e8b272686b5a799eabbcf..94ce3d7a1c4b9fe83b42954d309c8ac93b284ff5 100644 (file)
@@ -910,6 +910,7 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_JOURNAL_CHECKSUM    0x800000 /* Journal checksums */
 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT        0x1000000 /* Journal Async Commit */
 #define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
+#define EXT4_MOUNT_MBLK_IO_SUBMIT      0x4000000 /* multi-block io submits */
 #define EXT4_MOUNT_DELALLOC            0x8000000 /* Delalloc support */
 #define EXT4_MOUNT_DATA_ERR_ABORT      0x10000000 /* Abort on file data write */
 #define EXT4_MOUNT_BLOCK_VALIDITY      0x20000000 /* Block validity checking */
index bdbe69902207c151df025d98690c4c016cf0b0e9..e659597b690b508e1325182de702031a73843f4d 100644 (file)
@@ -2125,9 +2125,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
                         */
                        if (unlikely(journal_data && PageChecked(page)))
                                err = __ext4_journalled_writepage(page, len);
-                       else
+                       else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT))
                                err = ext4_bio_write_page(&io_submit, page,
                                                          len, mpd->wbc);
+                       else
+                               err = block_write_full_page(page,
+                                       noalloc_get_block_write, mpd->wbc);
 
                        if (!err)
                                mpd->pages_written++;
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 92203b8a099f076ebbc0d794b3356289096c663f..dc40e75cba8857e6068739646b4932bb315688fd 100644 (file)
@@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
        if (namelen > EXT4_NAME_LEN)
                return NULL;
        if ((namelen <= 2) && (name[0] == '.') &&
-           (name[1] == '.' || name[1] == '0')) {
+           (name[1] == '.' || name[1] == '\0')) {
                /*
                 * "." or ".." will only be in the first block
                 * NFS may look up ".."; "." should be handled by the VFS
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 bd63e692721981b6f5337a6edf59afae1585bd7c..c93bd1e651f586c653f32dd1231022124ad8d52f 100644 (file)
@@ -1025,6 +1025,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
            !(def_mount_opts & EXT4_DEFM_NODELALLOC))
                seq_puts(seq, ",nodelalloc");
 
+       if (test_opt(sb, MBLK_IO_SUBMIT))
+               seq_puts(seq, ",mblk_io_submit");
        if (sbi->s_stripe)
                seq_printf(seq, ",stripe=%lu", sbi->s_stripe);
        /*
@@ -1196,7 +1198,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 = {
@@ -1239,8 +1240,8 @@ enum {
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
        Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
        Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
-       Opt_stripe, Opt_delalloc, Opt_nodelalloc,
-       Opt_block_validity, Opt_noblock_validity,
+       Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
+       Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
        Opt_inode_readahead_blks, Opt_journal_ioprio,
        Opt_dioread_nolock, Opt_dioread_lock,
        Opt_discard, Opt_nodiscard,
@@ -1304,6 +1305,8 @@ static const match_table_t tokens = {
        {Opt_resize, "resize"},
        {Opt_delalloc, "delalloc"},
        {Opt_nodelalloc, "nodelalloc"},
+       {Opt_mblk_io_submit, "mblk_io_submit"},
+       {Opt_nomblk_io_submit, "nomblk_io_submit"},
        {Opt_block_validity, "block_validity"},
        {Opt_noblock_validity, "noblock_validity"},
        {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
@@ -1725,6 +1728,12 @@ set_qf_format:
                case Opt_nodelalloc:
                        clear_opt(sbi->s_mount_opt, DELALLOC);
                        break;
+               case Opt_mblk_io_submit:
+                       set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT);
+                       break;
+               case Opt_nomblk_io_submit:
+                       clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT);
+                       break;
                case Opt_stripe:
                        if (match_int(&args[0], &option))
                                return 0;
@@ -2798,9 +2807,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);
@@ -3267,13 +3273,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..8b984a2cebbda185af01a6d4d5f8c31c89fc6fbe 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/module.h>
+#include <linux/compat.h>
 
 static const struct file_operations fuse_direct_io_file_operations;
 
@@ -134,6 +135,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 +143,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)
@@ -1617,6 +1628,58 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
        return 0;
 }
 
+/*
+ * CUSE servers compiled on 32bit broke on 64bit kernels because the
+ * ABI was defined to be 'struct iovec' which is different on 32bit
+ * and 64bit.  Fortunately we can determine which structure the server
+ * used from the size of the reply.
+ */
+static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src,
+                                size_t transferred, unsigned count,
+                                bool is_compat)
+{
+#ifdef CONFIG_COMPAT
+       if (count * sizeof(struct compat_iovec) == transferred) {
+               struct compat_iovec *ciov = src;
+               unsigned i;
+
+               /*
+                * With this interface a 32bit server cannot support
+                * non-compat (i.e. ones coming from 64bit apps) ioctl
+                * requests
+                */
+               if (!is_compat)
+                       return -EINVAL;
+
+               for (i = 0; i < count; i++) {
+                       dst[i].iov_base = compat_ptr(ciov[i].iov_base);
+                       dst[i].iov_len = ciov[i].iov_len;
+               }
+               return 0;
+       }
+#endif
+
+       if (count * sizeof(struct iovec) != transferred)
+               return -EIO;
+
+       memcpy(dst, src, transferred);
+       return 0;
+}
+
+/* Make sure iov_length() won't overflow */
+static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
+{
+       size_t n;
+       u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
+
+       for (n = 0; n < count; n++) {
+               if (iov->iov_len > (size_t) max)
+                       return -ENOMEM;
+               max -= iov->iov_len;
+       }
+       return 0;
+}
+
 /*
  * For ioctls, there is no generic way to determine how much memory
  * needs to be read and/or written.  Furthermore, ioctls are allowed
@@ -1798,18 +1861,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
                    in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV)
                        goto out;
 
-               err = -EIO;
-               if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred)
-                       goto out;
-
-               /* okay, copy in iovs and retry */
                vaddr = kmap_atomic(pages[0], KM_USER0);
-               memcpy(page_address(iov_page), vaddr, transferred);
+               err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr,
+                                           transferred, in_iovs + out_iovs,
+                                           (flags & FUSE_IOCTL_COMPAT) != 0);
                kunmap_atomic(vaddr, KM_USER0);
+               if (err)
+                       goto out;
 
                in_iov = page_address(iov_page);
                out_iov = in_iov + in_iovs;
 
+               err = fuse_verify_ioctl_iov(in_iov, in_iovs);
+               if (err)
+                       goto out;
+
+               err = fuse_verify_ioctl_iov(out_iov, out_iovs);
+               if (err)
+                       goto out;
+
                goto retry;
        }
 
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 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..996dd8989a9135203cab110f57e7c1f8df49e200 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"
@@ -56,7 +57,7 @@ static int nfs_rename(struct inode *, struct dentry *,
                      struct inode *, struct dentry *);
 static int nfs_fsync_dir(struct file *, int);
 static loff_t nfs_llseek_dir(struct file *, loff_t, int);
-static int nfs_readdir_clear_array(struct page*, gfp_t);
+static void nfs_readdir_clear_array(struct page*);
 
 const struct file_operations nfs_dir_operations = {
        .llseek         = nfs_llseek_dir,
@@ -82,8 +83,8 @@ const struct inode_operations nfs_dir_inode_operations = {
        .setattr        = nfs_setattr,
 };
 
-const struct address_space_operations nfs_dir_addr_space_ops = {
-       .releasepage = nfs_readdir_clear_array,
+const struct address_space_operations nfs_dir_aops = {
+       .freepage = nfs_readdir_clear_array,
 };
 
 #ifdef CONFIG_NFS_V3
@@ -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,14 +172,13 @@ 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;
        struct page     *page;
        unsigned long   page_index;
        u64             *dir_cookie;
+       u64             last_cookie;
        loff_t          current_index;
        decode_dirent_t decode;
 
@@ -194,9 +195,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
@@ -209,14 +214,15 @@ void nfs_readdir_release_array(struct page *page)
  * we are freeing strings created by nfs_add_to_readdir_array()
  */
 static
-int nfs_readdir_clear_array(struct page *page, gfp_t mask)
+void nfs_readdir_clear_array(struct page *page)
 {
-       struct nfs_cache_array *array = nfs_readdir_get_array(page);
+       struct nfs_cache_array *array;
        int i;
+
+       array = kmap_atomic(page, KM_USER0);
        for (i = 0; i < array->size; i++)
                kfree(array->array[i].string.name);
-       nfs_readdir_release_array(page);
-       return 0;
+       kunmap_atomic(array, KM_USER0);
 }
 
 /*
@@ -231,6 +237,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 +255,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;
-       if (entry->eof == 1)
-               array->eof_index = array->size;
        array->size++;
+       if (entry->eof != 0)
+               array->eof_index = array->size;
 out:
        nfs_readdir_release_array(page);
        return ret;
@@ -272,7 +287,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 +296,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 +309,16 @@ 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;
+                       return 0;
                }
        }
-
+       if (array->eof_index >= 0) {
+               status = -EBADCOOKIE;
+               if (*desc->dir_cookie == array->last_cookie)
+                       desc->eof = 1;
+       }
        return status;
 }
 
@@ -314,10 +326,7 @@ static
 int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
 {
        struct nfs_cache_array *array;
-       int status = -EBADCOOKIE;
-
-       if (desc->dir_cookie == NULL)
-               goto out;
+       int status;
 
        array = nfs_readdir_get_array(desc->page);
        if (IS_ERR(array)) {
@@ -330,6 +339,10 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
        else
                status = nfs_readdir_search_for_cookie(array, desc);
 
+       if (status == -EAGAIN) {
+               desc->last_cookie = array->last_cookie;
+               desc->page_index++;
+       }
        nfs_readdir_release_array(desc->page);
 out:
        return status;
@@ -381,13 +394,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 +458,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 +481,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;
+               }
 
-               if (nfs_readdir_add_to_array(entry, page) == -1)
-                       break;
-               if (desc->plus == 1)
+               count++;
+
+               if (desc->plus != 0)
                        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 != 0)) {
                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,11 +558,11 @@ 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;
-       entry.cookie = *desc->dir_cookie;
+       entry.cookie = desc->last_cookie;
        entry.eof = 0;
        entry.fh = nfs_alloc_fhandle();
        entry.fattr = nfs_alloc_fattr();
@@ -549,6 +570,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 +581,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 +614,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,12 +629,14 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
        return 0;
  error:
        unlock_page(page);
-       return -EIO;
+       return ret;
 }
 
 static
 void cache_page_release(nfs_readdir_descriptor_t *desc)
 {
+       if (!desc->page->mapping)
+               nfs_readdir_clear_array(desc->page);
        page_cache_release(desc->page);
        desc->page = NULL;
 }
@@ -608,12 +644,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;
 }
 
 /*
@@ -629,9 +661,8 @@ int find_cache_page(nfs_readdir_descriptor_t *desc)
                return PTR_ERR(desc->page);
 
        res = nfs_readdir_search_array(desc);
-       if (res == 0)
-               return 0;
-       cache_page_release(desc);
+       if (res != 0)
+               cache_page_release(desc);
        return res;
 }
 
@@ -639,22 +670,18 @@ 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;
 
-       while (1) {
-               res = find_cache_page(desc);
-               if (res != -EAGAIN)
-                       break;
-               desc->page_index++;
+       if (desc->page_index == 0) {
+               desc->current_index = 0;
+               desc->last_cookie = 0;
        }
+       do {
+               res = find_cache_page(desc);
+       } while (res == -EAGAIN);
        return res;
 }
 
-static inline unsigned int dt_type(struct inode *inode)
-{
-       return (inode->i_mode >> 12) & 15;
-}
-
 /*
  * Once we've found the start of the dirent within a page: fill 'er up...
  */
@@ -666,35 +693,35 @@ 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 (array->eof_index >= 0)
+               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 +756,14 @@ 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->last_cookie = *desc->dir_cookie;
        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:
@@ -757,7 +785,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        struct inode    *inode = dentry->d_inode;
        nfs_readdir_descriptor_t my_desc,
                        *desc = &my_desc;
-       int res = -ENOMEM;
+       int res;
 
        dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
                        dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -782,18 +810,18 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if (res < 0)
                goto out;
 
-       while (desc->eof != 1) {
+       do {
                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,11 +836,9 @@ 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;
-               }
-       }
+       } while (!desc->eof);
 out:
        nfs_unblock_sillyrename(dentry);
        if (res > 0)
@@ -1345,12 +1371,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 60677f9f13110d1a98774595de819fddf2c0ccdf..7bf029ef4084c6e7f02e05e355382168e85e2cb8 100644 (file)
@@ -693,6 +693,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
 {
        struct inode *inode = filp->f_mapping->host;
        int status = 0;
+       unsigned int saved_type = fl->fl_type;
 
        /* Try local locking first */
        posix_test_lock(filp, fl);
@@ -700,6 +701,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
                /* found a conflict */
                goto out;
        }
+       fl->fl_type = saved_type;
 
        if (nfs_have_delegation(inode, FMODE_READ))
                goto out_noconflict;
index 314f57164602eda0762c0a226db44aa19be461f5..e67e31c734163c6fe6c0eef0d338a2b87ae55763 100644 (file)
@@ -289,6 +289,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                } else if (S_ISDIR(inode->i_mode)) {
                        inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
                        inode->i_fop = &nfs_dir_operations;
+                       inode->i_data.a_ops = &nfs_dir_aops;
                        if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS))
                                set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
                        /* Deal with crossing mountpoints */
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 eceafe74f4737ea5fbcea90b8ac19749737667b9..4f981f1f668925cba6bebe6ed4cf485da6a56dbb 100644 (file)
@@ -505,13 +505,13 @@ static struct rpc_procinfo mnt3_procedures[] = {
 
 static struct rpc_version mnt_version1 = {
        .number         = 1,
-       .nrprocs        = 2,
+       .nrprocs        = ARRAY_SIZE(mnt_procedures),
        .procs          = mnt_procedures,
 };
 
 static struct rpc_version mnt_version3 = {
        .number         = 3,
-       .nrprocs        = 2,
+       .nrprocs        = ARRAY_SIZE(mnt3_procedures),
        .procs          = mnt3_procedures,
 };
 
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..4435e5e1f904e3e5ba26f4eb578fc30c5f6d997b 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);
 
@@ -3359,6 +3361,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
        ret = nfs_revalidate_inode(server, inode);
        if (ret < 0)
                return ret;
+       if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
+               nfs_zap_acl_cache(inode);
        ret = nfs4_read_cached_acl(inode, buf, buflen);
        if (ret != -ENOENT)
                return ret;
@@ -3387,6 +3391,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
        nfs_inode_return_delegation(inode);
        buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
        ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
+       /*
+        * Acl update can result in inode attribute update.
+        * so mark the attribute cache invalid.
+        */
+       spin_lock(&inode->i_lock);
+       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
+       spin_unlock(&inode->i_lock);
        nfs_access_zap_cache(inode);
        nfs_zap_acl_cache(inode);
        return ret;
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 137b549e63dbcfa3971aac43091eb91a29a7b69f..b68536cc9046ec937b9b4ccddb98b2acf468f1db 100644 (file)
@@ -115,7 +115,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
 {
        if (!nfs_lock_request_dontget(req))
                return 0;
-       if (req->wb_page != NULL)
+       if (test_bit(PG_MAPPED, &req->wb_flags))
                radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
        return 1;
 }
@@ -125,7 +125,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
  */
 void nfs_clear_page_tag_locked(struct nfs_page *req)
 {
-       if (req->wb_page != NULL) {
+       if (test_bit(PG_MAPPED, &req->wb_flags)) {
                struct inode *inode = req->wb_context->path.dentry->d_inode;
                struct nfs_inode *nfsi = NFS_I(inode);
 
index e4b62c6f5a6e9eb721eda53d836c41055ab2e1b7..aedcaa7f291fbe4405f2b68c13f407c7de6be9ba 100644 (file)
@@ -152,7 +152,6 @@ static void nfs_readpage_release(struct nfs_page *req)
                        (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
                        req->wb_bytes,
                        (long long)req_offset(req));
-       nfs_clear_request(req);
        nfs_release_request(req);
 }
 
index 0a42e8f4adcbc1723b57a7dac93c78b0a34b975e..4100630c9a5b65f47bb5379ee2bc62f78e60284e 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,
@@ -1064,12 +1069,10 @@ static int nfs_parse_mount_options(char *raw,
                        mnt->flags |= NFS_MOUNT_VER3;
                        mnt->version = 3;
                        break;
-#ifdef CONFIG_NFS_V4
                case Opt_v4:
                        mnt->flags &= ~NFS_MOUNT_VER3;
                        mnt->version = 4;
                        break;
-#endif
                case Opt_udp:
                        mnt->flags &= ~NFS_MOUNT_TCP;
                        mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1281,12 +1284,10 @@ static int nfs_parse_mount_options(char *raw,
                                mnt->flags |= NFS_MOUNT_VER3;
                                mnt->version = 3;
                                break;
-#ifdef CONFIG_NFS_V4
                        case NFS4_VERSION:
                                mnt->flags &= ~NFS_MOUNT_VER3;
                                mnt->version = 4;
                                break;
-#endif
                        default:
                                goto out_invalid_value;
                        }
@@ -2277,7 +2278,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 4c14c17a5276a410bb383e3650f106ab56cf47d6..10d648ea128bf6345df70da0e15ee8ce443ab8e6 100644 (file)
@@ -390,6 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
                if (nfs_have_delegation(inode, FMODE_WRITE))
                        nfsi->change_attr++;
        }
+       set_bit(PG_MAPPED, &req->wb_flags);
        SetPagePrivate(req->wb_page);
        set_page_private(req->wb_page, (unsigned long)req);
        nfsi->npages++;
@@ -415,6 +416,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
        spin_lock(&inode->i_lock);
        set_page_private(req->wb_page, 0);
        ClearPagePrivate(req->wb_page);
+       clear_bit(PG_MAPPED, &req->wb_flags);
        radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
        nfsi->npages--;
        if (!nfsi->npages) {
@@ -422,7 +424,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
                iput(inode);
        } else
                spin_unlock(&inode->i_lock);
-       nfs_clear_request(req);
        nfs_release_request(req);
 }
 
index 2a533a0af2a98ed91afb84e71669d328cb67a866..7e84a852cdae8117334fec6ee00d085fc29c0c66 100644 (file)
@@ -260,9 +260,11 @@ void fill_post_wcc(struct svc_fh *fhp)
        err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
                        &fhp->fh_post_attr);
        fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version;
-       if (err)
+       if (err) {
                fhp->fh_post_saved = 0;
-       else
+               /* Grab the ctime anyway - set_change_info might use it */
+               fhp->fh_post_attr.ctime = fhp->fh_dentry->d_inode->i_ctime;
+       } else
                fhp->fh_post_saved = 1;
 }
 
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 4d476ff08ae6add1ec3a1b597909f1375af78b7b..60fce3dc5cb5d9f90d22b9f9c91ddc7ddeb9ff1d 100644 (file)
@@ -484,18 +484,17 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
 static inline void
 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 {
-       BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
-       cinfo->atomic = 1;
+       BUG_ON(!fhp->fh_pre_saved);
+       cinfo->atomic = fhp->fh_post_saved;
        cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
-       if (cinfo->change_supported) {
-               cinfo->before_change = fhp->fh_pre_change;
-               cinfo->after_change = fhp->fh_post_change;
-       } else {
-               cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
-               cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
-               cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
-               cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
-       }
+
+       cinfo->before_change = fhp->fh_pre_change;
+       cinfo->after_change = fhp->fh_post_change;
+       cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+       cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+       cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
+       cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
+
 }
 
 int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
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 d0a2721eacebd17f14d91bc75927d5ff152d8c27..ec0fdc3ebe979dd87bdad862c2a8fdfe6949bf33 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 e2fce519c0f2df11354f11c56a2dbff422b51de1..3eea859e6990ca90601ba7fef043103b87f98745 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 d2026382ac3eee2fb7716efa094809edd5657c48..50a5d978da1698f68cf8d2d2eca97474887ea223 100644 (file)
@@ -1300,18 +1300,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.
@@ -1325,8 +1313,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)
@@ -1540,7 +1528,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;
 
@@ -1627,7 +1615,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;
 
@@ -2007,8 +1995,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 d2af0a8381a63975e9668d1aa7babb942bd4f4e2..77a59891734e925318f4a91723f96eb55f7b5ae8 100644 (file)
@@ -297,6 +297,7 @@ xfs_rename(
         * it and some incremental backup programs won't work without it.
         */
        xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG);
+       xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE);
 
        /*
         * Adjust the link count on src_dp.  This is necessary when
index 551793c9b6e8c25b2b1d3e36a4fe8ffcb4a0f24a..0e98e679d3a749cfda3898c2fe59f82d18ca87c3 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef __ACPI_VIDEO_H
 #define __ACPI_VIDEO_H
 
+#include <linux/errno.h> /* for ENODEV */
+
+struct acpi_device;
+
 #define ACPI_VIDEO_DISPLAY_CRT  1
 #define ACPI_VIDEO_DISPLAY_TV   2
 #define ACPI_VIDEO_DISPLAY_DVI  3
@@ -26,4 +30,3 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type,
 #endif
 
 #endif
-
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 050a7bccb8365ef117f365ebe3d3a8d337efc390..67c91b4418b06e59ea9de82e0c67dfb4cc5a7554 100644 (file)
@@ -219,7 +219,7 @@ static inline int acpi_video_display_switch_support(void)
 
 extern int acpi_blacklisted(void);
 extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
-extern int acpi_osi_setup(char *str);
+extern void acpi_osi_setup(char *str);
 
 #ifdef CONFIG_ACPI_NUMA
 int acpi_get_pxm(acpi_handle handle);
index a8e4e832cdbb094d8a99ad9d831db3d14cbdbe23..475f8c42c0e928b57fbaf370bb89471642391b77 100644 (file)
@@ -427,8 +427,10 @@ extern rwlock_t vcc_sklist_lock;
 
 #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
 
-struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
-    int number,unsigned long *flags); /* number == -1: pick first available */
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+                                const struct atmdev_ops *ops,
+                                int number, /* -1 == pick first available */
+                                unsigned long *flags);
 struct atm_dev *atm_dev_lookup(int number);
 void atm_dev_deregister(struct atm_dev *dev);
 
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 997d22efdef074ec841d2ec01e0b03a28e39fdc3..34209283eab6e7038dca99d37f0f41fd1c1ac80a 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: */
@@ -602,6 +602,7 @@ struct address_space_operations {
        sector_t (*bmap)(struct address_space *, sector_t);
        void (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, gfp_t);
+       void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        int (*get_xip_mem)(struct address_space *, pgoff_t, int,
@@ -1613,7 +1614,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 a2d6ea49ec564e825ebffc3ebb059f57079fc73d..d1e55fed2c7dc0281cd0cf653bb5a56a399265cb 100644 (file)
@@ -33,6 +33,8 @@ enum bp_type_idx {
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 
+extern int __init init_hw_breakpoint(void);
+
 static inline void hw_breakpoint_init(struct perf_event_attr *attr)
 {
        memset(attr, 0, sizeof(*attr));
@@ -108,6 +110,8 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
 
 #else /* !CONFIG_HAVE_HW_BREAKPOINT */
 
+static inline int __init init_hw_breakpoint(void) { return 0; }
+
 static inline struct perf_event *
 register_user_hw_breakpoint(struct perf_event_attr *attr,
                            perf_overflow_handler_t triggered,
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 5c51f367c0610166bbf6ec12d6fedc7587d7420e..add8a1b8bcf0057c3f328c51dc96a4d82ae331a5 100644 (file)
@@ -29,7 +29,7 @@ struct wm8994_ldo_pdata {
 #define WM8994_CONFIGURE_GPIO 0x8000
 
 #define WM8994_DRC_REGS 5
-#define WM8994_EQ_REGS  19
+#define WM8994_EQ_REGS  20
 
 /**
  * DRC configurations are specified with a label and a set of register
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..29d504d5d1c31f5698433657dd534c1500f317b2 100644 (file)
@@ -401,6 +401,7 @@ extern const struct inode_operations nfs3_file_inode_operations;
 #endif /* CONFIG_NFS_V3 */
 extern const struct file_operations nfs_file_operations;
 extern const struct address_space_operations nfs_file_aops;
+extern const struct address_space_operations nfs_dir_aops;
 
 static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
 {
@@ -593,12 +594,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 f8b60e7f4c44d9b652a94bca2ab8945130bdb061..d55cee73f63477a326b73cf7eb15e3e277567b14 100644 (file)
@@ -29,6 +29,7 @@
  */
 enum {
        PG_BUSY = 0,
+       PG_MAPPED,
        PG_CLEAN,
        PG_NEED_COMMIT,
        PG_NEED_RESCHED,
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 40150f345982cd4fd40e8b80470505e569f05b03..de2c41758e29e20d6a709303f21a6d8242696fa0 100644 (file)
@@ -850,6 +850,7 @@ struct perf_event_context {
        int                             nr_active;
        int                             is_active;
        int                             nr_stat;
+       int                             rotate_disable;
        atomic_t                        refcount;
        struct task_struct              *task;
 
@@ -908,20 +909,6 @@ extern int perf_num_counters(void);
 extern const char *perf_pmu_name(void);
 extern void __perf_event_task_sched_in(struct task_struct *task);
 extern void __perf_event_task_sched_out(struct task_struct *task, struct task_struct *next);
-
-extern atomic_t perf_task_events;
-
-static inline void perf_event_task_sched_in(struct task_struct *task)
-{
-       COND_STMT(&perf_task_events, __perf_event_task_sched_in(task));
-}
-
-static inline
-void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next)
-{
-       COND_STMT(&perf_task_events, __perf_event_task_sched_out(task, next));
-}
-
 extern int perf_event_init_task(struct task_struct *child);
 extern void perf_event_exit_task(struct task_struct *child);
 extern void perf_event_free_task(struct task_struct *task);
@@ -1030,6 +1017,21 @@ have_event:
        __perf_sw_event(event_id, nr, nmi, regs, addr);
 }
 
+extern atomic_t perf_task_events;
+
+static inline void perf_event_task_sched_in(struct task_struct *task)
+{
+       COND_STMT(&perf_task_events, __perf_event_task_sched_in(task));
+}
+
+static inline
+void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next)
+{
+       perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
+
+       COND_STMT(&perf_task_events, __perf_event_task_sched_out(task, next));
+}
+
 extern void perf_event_mmap(struct vm_area_struct *vma);
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
 extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
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 ebb0c80ffd6ebb53b02fb2263e0a6ff6a634eb6a..12b2b18e50c1c321f208a83d4bbda61ce985450c 100644 (file)
@@ -230,6 +230,7 @@ enum
        LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
        LINUX_MIB_TCPDEFERACCEPTDROP,
        LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */
+       LINUX_MIB_TCPTIMEWAITOVERFLOW,          /* TCPTimeWaitOverflow */
        __LINUX_MIB_MAX
 };
 
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 2fb46bc9340d9b40617042ba8bb253754e4b6f67..ed5cdeb3604dbe6ea1fe807b33a69bf140d1622a 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef _LINUX_VIDEO_OUTPUT_H
 #define _LINUX_VIDEO_OUTPUT_H
 #include <linux/device.h>
+#include <linux/err.h>
 struct output_device;
 struct output_properties {
        int (*set_state)(struct output_device *);
@@ -34,9 +35,23 @@ struct output_device {
        struct device dev;
 };
 #define to_output_device(obj) container_of(obj, struct output_device, dev)
+#if    defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE)
 struct output_device *video_output_register(const char *name,
        struct device *dev,
        void *devdata,
        struct output_properties *op);
 void video_output_unregister(struct output_device *dev);
+#else
+static struct output_device *video_output_register(const char *name,
+        struct device *dev,
+        void *devdata,
+        struct output_properties *op)
+{
+       return ERR_PTR(-ENODEV);
+}
+static void video_output_unregister(struct output_device *dev)
+{
+       return;
+}
+#endif
 #endif
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 a6338d039857bf6b00bcff087f974ebf46ae0875..659d968d95c54afe6df51c3289a0d2d6fb5b34ed 100644 (file)
@@ -1155,6 +1155,8 @@ extern void sk_common_release(struct sock *sk);
 /* Initialise core socket variables */
 extern void sock_init_data(struct socket *sock, struct sock *sk);
 
+extern void sk_filter_release_rcu(struct rcu_head *rcu);
+
 /**
  *     sk_filter_release - release a socket filter
  *     @fp: filter to remove
@@ -1165,7 +1167,7 @@ extern void sock_init_data(struct socket *sock, struct sock *sk);
 static inline void sk_filter_release(struct sk_filter *fp)
 {
        if (atomic_dec_and_test(&fp->refcnt))
-               kfree(fp);
+               call_rcu_bh(&fp->rcu, sk_filter_release_rcu);
 }
 
 static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
index f986ab7ffe6f040e9e00ac23d404bd8ad31e1f4e..f53c8e31d5fba1f3e5a59e0104fcaf5980319fde 100644 (file)
@@ -221,8 +221,8 @@ struct fc_rport_priv {
  * @InputRequests:         Number of input requests
  * @OutputRequests:        Number of output requests
  * @ControlRequests:       Number of control requests
- * @InputMegabytes:        Number of received megabytes
- * @OutputMegabytes:       Number of transmitted megabytes
+ * @InputBytes:            Number of received bytes
+ * @OutputBytes:           Number of transmitted bytes
  * @VLinkFailureCount:     Number of virtual link failures
  * @MissDiscAdvCount:      Number of missing FIP discovery advertisement
  */
@@ -241,8 +241,8 @@ struct fcoe_dev_stats {
        u64             InputRequests;
        u64             OutputRequests;
        u64             ControlRequests;
-       u64             InputMegabytes;
-       u64             OutputMegabytes;
+       u64             InputBytes;
+       u64             OutputBytes;
        u64             VLinkFailureCount;
        u64             MissDiscAdvCount;
 };
@@ -263,7 +263,6 @@ struct fc_seq_els_data {
  * struct fc_fcp_pkt - FCP request structure (one for each scsi_cmnd request)
  * @lp:              The associated local port
  * @state:           The state of the I/O
- * @tgt_flags:       Target's flags
  * @ref_cnt:         Reference count
  * @scsi_pkt_lock:   Lock to protect the SCSI packet (must be taken before the
  *                   host_lock if both are to be held at the same time)
@@ -298,7 +297,6 @@ struct fc_fcp_pkt {
        /* Housekeeping information */
        struct fc_lport   *lp;
        u16               state;
-       u16               tgt_flags;
        atomic_t          ref_cnt;
        spinlock_t        scsi_pkt_lock;
 
@@ -1006,8 +1004,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 06f1b5a8ed1943ce40050a73136478c64130baea..feb6a94c90eae10c8c23207134caebe69ac52b6a 100644 (file)
@@ -92,10 +92,12 @@ enum fip_state {
  * @timer_work:           &work_struct for doing keep-alives and resets.
  * @recv_work:    &work_struct for receiving FIP frames.
  * @fip_recv_list: list of received FIP frames.
+ * @flogi_req:    clone of FLOGI request sent
  * @rnd_state:    state for pseudo-random number generator.
  * @port_id:      proposed or selected local-port ID.
  * @user_mfs:     configured maximum FC frame size, including FC header.
  * @flogi_oxid:    exchange ID of most recent fabric login.
+ * @flogi_req_send: send of FLOGI requested
  * @flogi_count:   number of FLOGI attempts in AUTO mode.
  * @map_dest:     use the FC_MAP mode for destination MAC addresses.
  * @spma:         supports SPMA server-provided MACs mode
@@ -106,6 +108,7 @@ enum fip_state {
  * @update_mac:    LLD-supplied function to handle changes to MAC addresses.
  * @get_src_addr:  LLD-supplied function to supply a source MAC address.
  * @ctlr_mutex:           lock protecting this structure.
+ * @ctlr_lock:     spinlock covering flogi_req
  *
  * This structure is used by all FCoE drivers.  It contains information
  * needed by all FCoE low-level drivers (LLDs) as well as internal state
@@ -126,12 +129,14 @@ struct fcoe_ctlr {
        struct work_struct timer_work;
        struct work_struct recv_work;
        struct sk_buff_head fip_recv_list;
+       struct sk_buff *flogi_req;
 
        struct rnd_state rnd_state;
        u32 port_id;
 
        u16 user_mfs;
        u16 flogi_oxid;
+       u8 flogi_req_send;
        u8 flogi_count;
        u8 map_dest;
        u8 spma;
@@ -143,6 +148,7 @@ struct fcoe_ctlr {
        void (*update_mac)(struct fc_lport *, u8 *addr);
        u8 * (*get_src_addr)(struct fc_lport *);
        struct mutex ctlr_mutex;
+       spinlock_t ctlr_lock;
 };
 
 /**
@@ -155,6 +161,7 @@ struct fcoe_ctlr {
  * @fcf_mac:    Ethernet address of the FCF
  * @vfid:       virtual fabric ID
  * @pri:        selection priority, smaller values are better
+ * @flogi_sent:         current FLOGI sent to this FCF
  * @flags:      flags received from advertisement
  * @fka_period:         keep-alive period, in jiffies
  *
@@ -176,6 +183,7 @@ struct fcoe_fcf {
        u8 fcf_mac[ETH_ALEN];
 
        u8 pri;
+       u8 flogi_sent;
        u16 flags;
        u32 fka_period;
        u8 fd_flags:1;
index ae5196aae1a5311421e72ba22d9b9f43cb748500..68e951d79f0b1f03f90aa5895496244f93398576 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.
@@ -420,6 +419,7 @@ extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
 extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);
 extern void iscsi_requeue_task(struct iscsi_task *task);
 extern void iscsi_put_task(struct iscsi_task *task);
+extern void __iscsi_put_task(struct iscsi_task *task);
 extern void __iscsi_get_task(struct iscsi_task *task);
 extern void iscsi_complete_scsi_task(struct iscsi_task *task,
                                     uint32_t exp_cmdsn, uint32_t max_cmdsn);
index 3dec1949f69cd75890368d40700f68399ac68427..8f6bb9c7f3eb1b038a784e4d706098f3442937ba 100644 (file)
@@ -361,6 +361,8 @@ struct sas_ha_struct {
        /* The class calls this to send a task for execution. */
        int lldd_max_execute_num;
        int lldd_queue_size;
+       int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
+                               * their siblings when forming wide ports */
 
        /* LLDD calls these to notify the class of an event. */
        void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
@@ -621,8 +623,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 86758618d4f807c31894beb1b3fcd6ba42c7e51d..648d233580387bb57b584508c748eccee8da9f21 100644 (file)
@@ -116,33 +116,61 @@ struct scsi_cmnd;
 #define PERSISTENT_RESERVE_OUT 0x5f
 #define VARIABLE_LENGTH_CMD   0x7f
 #define REPORT_LUNS           0xa0
+#define SECURITY_PROTOCOL_IN  0xa2
 #define MAINTENANCE_IN        0xa3
 #define MAINTENANCE_OUT       0xa4
 #define MOVE_MEDIUM           0xa5
 #define EXCHANGE_MEDIUM       0xa6
 #define READ_12               0xa8
 #define WRITE_12              0xaa
+#define READ_MEDIA_SERIAL_NUMBER 0xab
 #define WRITE_VERIFY_12       0xae
 #define VERIFY_12            0xaf
 #define SEARCH_HIGH_12        0xb0
 #define SEARCH_EQUAL_12       0xb1
 #define SEARCH_LOW_12         0xb2
+#define SECURITY_PROTOCOL_OUT 0xb5
 #define READ_ELEMENT_STATUS   0xb8
 #define SEND_VOLUME_TAG       0xb6
 #define WRITE_LONG_2          0xea
+#define EXTENDED_COPY         0x83
+#define RECEIVE_COPY_RESULTS  0x84
+#define ACCESS_CONTROL_IN     0x86
+#define ACCESS_CONTROL_OUT    0x87
 #define READ_16               0x88
 #define WRITE_16              0x8a
+#define READ_ATTRIBUTE        0x8c
+#define WRITE_ATTRIBUTE              0x8d
 #define VERIFY_16            0x8f
 #define WRITE_SAME_16        0x93
 #define SERVICE_ACTION_IN     0x9e
 /* values for service action in */
 #define        SAI_READ_CAPACITY_16  0x10
 #define SAI_GET_LBA_STATUS    0x12
+/* values for VARIABLE_LENGTH_CMD service action codes
+ * see spc4r17 Section D.3.5, table D.7 and D.8 */
+#define VLC_SA_RECEIVE_CREDENTIAL 0x1800
 /* values for maintenance in */
+#define MI_REPORT_IDENTIFYING_INFORMATION 0x05
 #define MI_REPORT_TARGET_PGS  0x0a
+#define MI_REPORT_ALIASES     0x0b
+#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c
+#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d
+#define MI_REPORT_PRIORITY   0x0e
+#define MI_REPORT_TIMESTAMP  0x0f
+#define MI_MANAGEMENT_PROTOCOL_IN 0x10
 /* values for maintenance out */
+#define MO_SET_IDENTIFYING_INFORMATION 0x06
 #define MO_SET_TARGET_PGS     0x0a
+#define MO_CHANGE_ALIASES     0x0b
+#define MO_SET_PRIORITY       0x0e
+#define MO_SET_TIMESTAMP      0x0f
+#define MO_MANAGEMENT_PROTOCOL_OUT 0x10
 /* values for variable length command */
+#define XDREAD_32            0x03
+#define XDWRITE_32           0x04
+#define XPWRITE_32           0x06
+#define XDWRITEREAD_32       0x07
 #define READ_32                      0x09
 #define VERIFY_32            0x0a
 #define WRITE_32             0x0b
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 e8cbf431c8ccfd33f76fd018e8dd64ea6dd2c8b7..75271b9a8f61bedcec5a18465b5a9ca8e84a38c7 100644 (file)
@@ -24,8 +24,15 @@ typedef unsigned int RING_IDX;
  * A ring contains as many entries as will fit, rounded down to the nearest
  * power of two (so we can mask with (size-1) to loop around).
  */
-#define __RING_SIZE(_s, _sz) \
-    (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
+#define __CONST_RING_SIZE(_s, _sz)                             \
+       (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) /   \
+               sizeof(((struct _s##_sring *)0)->ring[0])))
+
+/*
+ * The same for passing in an actual pointer instead of a name tag.
+ */
+#define __RING_SIZE(_s, _sz)                                           \
+       (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
 
 /*
  * Macros to make the correct C datatypes for a new kind of ring.
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 2c9120f0afca9872cc4edba57d4e5cfe9311788f..e5325825aeb6e1e4ea0514ee37cfa53412ec4e3c 100644 (file)
@@ -620,7 +620,7 @@ static struct pmu perf_breakpoint = {
        .read           = hw_breakpoint_pmu_read,
 };
 
-static int __init init_hw_breakpoint(void)
+int __init init_hw_breakpoint(void)
 {
        unsigned int **task_bp_pinned;
        int cpu, err_cpu;
@@ -655,6 +655,5 @@ static int __init init_hw_breakpoint(void)
 
        return -ENOMEM;
 }
-core_initcall(init_hw_breakpoint);
 
 
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 f16763ff8481b727bdf0263c241ddf2e1d6ba09a..90f881904bb1202ba1566f5db2e28eaf128551b9 100644 (file)
@@ -145,7 +145,9 @@ void irq_work_run(void)
                 * Clear the BUSY bit and return to the free state if
                 * no-one else claimed it meanwhile.
                 */
-               cmpxchg(&entry->next, next_flags(NULL, IRQ_WORK_BUSY), NULL);
+               (void)cmpxchg(&entry->next,
+                             next_flags(NULL, IRQ_WORK_BUSY),
+                             NULL);
        }
 }
 EXPORT_SYMBOL_GPL(irq_work_run);
index 437a74a7524a7f592f669dbdc91a6c90503959ae..d190664f25ff3fa10dca29f37b483f08ad07eae1 100644 (file)
@@ -2326,6 +2326,18 @@ static void find_module_sections(struct module *mod, struct load_info *info)
        kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) *
                           mod->num_trace_events, GFP_KERNEL);
 #endif
+#ifdef CONFIG_TRACING
+       mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt",
+                                        sizeof(*mod->trace_bprintk_fmt_start),
+                                        &mod->num_trace_bprintk_fmt);
+       /*
+        * This section contains pointers to allocated objects in the trace
+        * code and not scanning it leads to false positives.
+        */
+       kmemleak_scan_area(mod->trace_bprintk_fmt_start,
+                          sizeof(*mod->trace_bprintk_fmt_start) *
+                          mod->num_trace_bprintk_fmt, GFP_KERNEL);
+#endif
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
        /* sechdrs[0].sh_size is always zero */
        mod->ftrace_callsites = section_objs(info, "__mcount_loc",
index cb6c0d2af68f64b16bd0557f3c7fb7001151b71d..eac7e3364335a7a3f94d902e69b9ed4eac4df74a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/perf_event.h>
 #include <linux/ftrace_event.h>
+#include <linux/hw_breakpoint.h>
 
 #include <asm/irq_regs.h>
 
@@ -1286,8 +1287,6 @@ void __perf_event_task_sched_out(struct task_struct *task,
 {
        int ctxn;
 
-       perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
-
        for_each_task_context_nr(ctxn)
                perf_event_context_sched_out(task, ctxn, next);
 }
@@ -1621,8 +1620,12 @@ static void rotate_ctx(struct perf_event_context *ctx)
 {
        raw_spin_lock(&ctx->lock);
 
-       /* Rotate the first entry last of non-pinned groups */
-       list_rotate_left(&ctx->flexible_groups);
+       /*
+        * Rotate the first entry last of non-pinned groups. Rotation might be
+        * disabled by the inheritance code.
+        */
+       if (!ctx->rotate_disable)
+               list_rotate_left(&ctx->flexible_groups);
 
        raw_spin_unlock(&ctx->lock);
 }
@@ -2234,11 +2237,6 @@ int perf_event_release_kernel(struct perf_event *event)
        raw_spin_unlock_irq(&ctx->lock);
        mutex_unlock(&ctx->mutex);
 
-       mutex_lock(&event->owner->perf_event_mutex);
-       list_del_init(&event->owner_entry);
-       mutex_unlock(&event->owner->perf_event_mutex);
-       put_task_struct(event->owner);
-
        free_event(event);
 
        return 0;
@@ -2251,9 +2249,43 @@ EXPORT_SYMBOL_GPL(perf_event_release_kernel);
 static int perf_release(struct inode *inode, struct file *file)
 {
        struct perf_event *event = file->private_data;
+       struct task_struct *owner;
 
        file->private_data = NULL;
 
+       rcu_read_lock();
+       owner = ACCESS_ONCE(event->owner);
+       /*
+        * Matches the smp_wmb() in perf_event_exit_task(). If we observe
+        * !owner it means the list deletion is complete and we can indeed
+        * free this event, otherwise we need to serialize on
+        * owner->perf_event_mutex.
+        */
+       smp_read_barrier_depends();
+       if (owner) {
+               /*
+                * Since delayed_put_task_struct() also drops the last
+                * task reference we can safely take a new reference
+                * while holding the rcu_read_lock().
+                */
+               get_task_struct(owner);
+       }
+       rcu_read_unlock();
+
+       if (owner) {
+               mutex_lock(&owner->perf_event_mutex);
+               /*
+                * We have to re-check the event->owner field, if it is cleared
+                * we raced with perf_event_exit_task(), acquiring the mutex
+                * ensured they're done, and we can proceed with freeing the
+                * event.
+                */
+               if (event->owner)
+                       list_del_init(&event->owner_entry);
+               mutex_unlock(&owner->perf_event_mutex);
+               put_task_struct(owner);
+       }
+
        return perf_event_release_kernel(event);
 }
 
@@ -5677,7 +5709,7 @@ SYSCALL_DEFINE5(perf_event_open,
        mutex_unlock(&ctx->mutex);
 
        event->owner = current;
-       get_task_struct(current);
+
        mutex_lock(&current->perf_event_mutex);
        list_add_tail(&event->owner_entry, &current->perf_event_list);
        mutex_unlock(&current->perf_event_mutex);
@@ -5745,12 +5777,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
        ++ctx->generation;
        mutex_unlock(&ctx->mutex);
 
-       event->owner = current;
-       get_task_struct(current);
-       mutex_lock(&current->perf_event_mutex);
-       list_add_tail(&event->owner_entry, &current->perf_event_list);
-       mutex_unlock(&current->perf_event_mutex);
-
        return event;
 
 err_free:
@@ -5901,8 +5927,24 @@ again:
  */
 void perf_event_exit_task(struct task_struct *child)
 {
+       struct perf_event *event, *tmp;
        int ctxn;
 
+       mutex_lock(&child->perf_event_mutex);
+       list_for_each_entry_safe(event, tmp, &child->perf_event_list,
+                                owner_entry) {
+               list_del_init(&event->owner_entry);
+
+               /*
+                * Ensure the list deletion is visible before we clear
+                * the owner, closes a race against perf_release() where
+                * we need to serialize on the owner->perf_event_mutex.
+                */
+               smp_wmb();
+               event->owner = NULL;
+       }
+       mutex_unlock(&child->perf_event_mutex);
+
        for_each_task_context_nr(ctxn)
                perf_event_exit_task_context(child, ctxn);
 }
@@ -6122,6 +6164,7 @@ int perf_event_init_context(struct task_struct *child, int ctxn)
        struct perf_event *event;
        struct task_struct *parent = current;
        int inherited_all = 1;
+       unsigned long flags;
        int ret = 0;
 
        child->perf_event_ctxp[ctxn] = NULL;
@@ -6162,6 +6205,15 @@ int perf_event_init_context(struct task_struct *child, int ctxn)
                        break;
        }
 
+       /*
+        * We can't hold ctx->lock when iterating the ->flexible_group list due
+        * to allocations, but we need to prevent rotation because
+        * rotate_ctx() will change the list from interrupt context.
+        */
+       raw_spin_lock_irqsave(&parent_ctx->lock, flags);
+       parent_ctx->rotate_disable = 1;
+       raw_spin_unlock_irqrestore(&parent_ctx->lock, flags);
+
        list_for_each_entry(event, &parent_ctx->flexible_groups, group_entry) {
                ret = inherit_task_group(event, parent, parent_ctx,
                                         child, ctxn, &inherited_all);
@@ -6169,6 +6221,10 @@ int perf_event_init_context(struct task_struct *child, int ctxn)
                        break;
        }
 
+       raw_spin_lock_irqsave(&parent_ctx->lock, flags);
+       parent_ctx->rotate_disable = 0;
+       raw_spin_unlock_irqrestore(&parent_ctx->lock, flags);
+
        child_ctx = child->perf_event_ctxp[ctxn];
 
        if (child_ctx && inherited_all) {
@@ -6321,6 +6377,8 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
 
 void __init perf_event_init(void)
 {
+       int ret;
+
        perf_event_init_all_cpus();
        init_srcu_struct(&pmus_srcu);
        perf_pmu_register(&perf_swevent);
@@ -6328,4 +6386,7 @@ void __init perf_event_init(void)
        perf_pmu_register(&perf_task_clock);
        perf_tp_register();
        perf_cpu_notifier(perf_cpu_notify);
+
+       ret = init_hw_breakpoint();
+       WARN(ret, "hw_breakpoint initialization failed with: %d", ret);
 }
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 b019609d1b4541e7b284e44477f9d46ace36e3a2..2d6f6e1091203e0b518cb51f114d40ec79584720 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 82d9b8106cd078970ea0c7343e12ad2b6a6eed36..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>
@@ -1284,6 +1283,8 @@ void trace_dump_stack(void)
        __ftrace_trace_stack(global_trace.buffer, flags, 3, preempt_count());
 }
 
+static DEFINE_PER_CPU(int, user_stack_count);
+
 void
 ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
 {
@@ -1302,6 +1303,18 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
        if (unlikely(in_nmi()))
                return;
 
+       /*
+        * prevent recursion, since the user stack tracing may
+        * trigger other kernel events.
+        */
+       preempt_disable();
+       if (__this_cpu_read(user_stack_count))
+               goto out;
+
+       __this_cpu_inc(user_stack_count);
+
+
+
        event = trace_buffer_lock_reserve(buffer, TRACE_USER_STACK,
                                          sizeof(*entry), flags, pc);
        if (!event)
@@ -1319,6 +1332,11 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
        save_stack_trace_user(&trace);
        if (!filter_check_discard(call, entry, buffer, event))
                ring_buffer_unlock_commit(buffer, event);
+
+       __this_cpu_dec(user_stack_count);
+
+ out:
+       preempt_enable();
 }
 
 #ifdef UNUSED
index 90db1bd1a97852e4c547c43d840b2ca624c9a773..e785b0f2aea57f362f9528fb979f15716f7f2aa4 100644 (file)
@@ -661,7 +661,7 @@ void wq_worker_waking_up(struct task_struct *task, unsigned int cpu)
 {
        struct worker *worker = kthread_data(task);
 
-       if (likely(!(worker->flags & WORKER_NOT_RUNNING)))
+       if (!(worker->flags & WORKER_NOT_RUNNING))
                atomic_inc(get_gcwq_nr_running(cpu));
 }
 
@@ -687,7 +687,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task,
        struct global_cwq *gcwq = get_gcwq(cpu);
        atomic_t *nr_running = get_gcwq_nr_running(cpu);
 
-       if (unlikely(worker->flags & WORKER_NOT_RUNNING))
+       if (worker->flags & WORKER_NOT_RUNNING)
                return NULL;
 
        /* this can only happen on the local cpu */
@@ -3692,7 +3692,8 @@ static int __init init_workqueues(void)
        system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0);
        system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
                                            WQ_UNBOUND_MAX_ACTIVE);
-       BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq);
+       BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq ||
+              !system_unbound_wq);
        return 0;
 }
 early_initcall(init_workqueues);
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 ea89840fc65fa2b499ce3c19c657e9e8a680b240..6b9aee20f2426b88024a25749402fc5ca1ff7a0a 100644 (file)
@@ -143,13 +143,18 @@ void __remove_from_page_cache(struct page *page)
 void remove_from_page_cache(struct page *page)
 {
        struct address_space *mapping = page->mapping;
+       void (*freepage)(struct page *);
 
        BUG_ON(!PageLocked(page));
 
+       freepage = mapping->a_ops->freepage;
        spin_lock_irq(&mapping->tree_lock);
        __remove_from_page_cache(page);
        spin_unlock_irq(&mapping->tree_lock);
        mem_cgroup_uncharge_cache_page(page);
+
+       if (freepage)
+               freepage(page);
 }
 EXPORT_SYMBOL(remove_from_page_cache);
 
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 b179abb1474ae41bff47060b5241045d3b1b12ad..50a4aa0255a0703f83c8667028afe8545d78e09a 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2462,6 +2462,7 @@ int install_special_mapping(struct mm_struct *mm,
                            unsigned long addr, unsigned long len,
                            unsigned long vm_flags, struct page **pages)
 {
+       int ret;
        struct vm_area_struct *vma;
 
        vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
@@ -2479,16 +2480,23 @@ int install_special_mapping(struct mm_struct *mm,
        vma->vm_ops = &special_mapping_vmops;
        vma->vm_private_data = pages;
 
-       if (unlikely(insert_vm_struct(mm, vma))) {
-               kmem_cache_free(vm_area_cachep, vma);
-               return -ENOMEM;
-       }
+       ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+       if (ret)
+               goto out;
+
+       ret = insert_vm_struct(mm, vma);
+       if (ret)
+               goto out;
 
        mm->total_vm += len >> PAGE_SHIFT;
 
        perf_event_mmap(vma);
 
        return 0;
+
+out:
+       kmem_cache_free(vm_area_cachep, vma);
+       return ret;
 }
 
 static DEFINE_MUTEX(mm_all_locks_mutex);
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 ba887bff48c5a263c315a6ef098284df4df5bb44..3c2d5ddfa0d49f3cf31449e214d8fbd50e92ad08 100644 (file)
@@ -390,6 +390,10 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
        __remove_from_page_cache(page);
        spin_unlock_irq(&mapping->tree_lock);
        mem_cgroup_uncharge_cache_page(page);
+
+       if (mapping->a_ops->freepage)
+               mapping->a_ops->freepage(page);
+
        page_cache_release(page);       /* pagecache ref */
        return 1;
 failed:
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 d31d7ce52c0ea2dbbf85b26019c9fdd70fab624a..9ca587c692748adbc715b440ff5aa8c89357c511 100644 (file)
@@ -494,9 +494,16 @@ static int __remove_mapping(struct address_space *mapping, struct page *page)
                spin_unlock_irq(&mapping->tree_lock);
                swapcache_free(swap, page);
        } else {
+               void (*freepage)(struct page *);
+
+               freepage = mapping->a_ops->freepage;
+
                __remove_from_page_cache(page);
                spin_unlock_irq(&mapping->tree_lock);
                mem_cgroup_uncharge_cache_page(page);
+
+               if (freepage != NULL)
+                       freepage(page);
        }
 
        return 1;
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 799c631f0fed0c1e8210d2d61e3fdf3afd27aea9..f7fa67c78766f59c0b107ece600348f401a40d57 100644 (file)
@@ -143,12 +143,13 @@ static struct class atm_class = {
        .dev_uevent             = atm_uevent,
 };
 
-int atm_register_sysfs(struct atm_dev *adev)
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent)
 {
        struct device *cdev = &adev->class_dev;
        int i, j, err;
 
        cdev->class = &atm_class;
+       cdev->parent = parent;
        dev_set_drvdata(cdev, adev);
 
        dev_set_name(cdev, "%s%d", adev->type, adev->number);
index d29e582615116a68e1f476091c6475d589401878..23f45ce6f3510fb1e9b30b58b7e52fac6a456961 100644 (file)
@@ -74,8 +74,9 @@ struct atm_dev *atm_dev_lookup(int number)
 }
 EXPORT_SYMBOL(atm_dev_lookup);
 
-struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
-                                int number, unsigned long *flags)
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+                                const struct atmdev_ops *ops, int number,
+                                unsigned long *flags)
 {
        struct atm_dev *dev, *inuse;
 
@@ -115,7 +116,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
                goto out_fail;
        }
 
-       if (atm_register_sysfs(dev) < 0) {
+       if (atm_register_sysfs(dev, parent) < 0) {
                pr_err("atm_register_sysfs failed for dev %s\n", type);
                atm_proc_dev_deregister(dev);
                goto out_fail;
index 126fb1840dfbb2ddd853602892e1a5e740bd90ac..521431e305073acc8c418c56317c09bb13b4731d 100644 (file)
@@ -42,6 +42,6 @@ static inline void atm_proc_dev_deregister(struct atm_dev *dev)
 
 #endif /* CONFIG_PROC_FS */
 
-int atm_register_sysfs(struct atm_dev *adev);
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent);
 void atm_unregister_sysfs(struct atm_dev *adev);
 #endif
index d0927d1fdadaba4887dbac40064c4328541b9b00..66b9e5c0523a2211450cece91d5cf217fbd4722b 100644 (file)
@@ -882,7 +882,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
        int lm = 0;
 
        if (type != SCO_LINK && type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
 
@@ -908,7 +908,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
        BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
        if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        if (!status) {
                struct sco_conn *conn;
@@ -927,7 +927,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
        BT_DBG("hcon %p reason %d", hcon, reason);
 
        if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        sco_conn_del(hcon, bt_err(reason));
 
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..ae21a0d3c4a2a4566c3792476e07ce0d2d2ece38 100644 (file)
@@ -589,23 +589,16 @@ 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_release_rcu - 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)
+void sk_filter_release_rcu(struct rcu_head *rcu)
 {
        struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
 
-       sk_filter_release(fp);
-}
-
-static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
-{
-       unsigned int size = sk_filter_len(fp);
-
-       atomic_sub(size, &sk->sk_omem_alloc);
-       call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
+       kfree(fp);
 }
+EXPORT_SYMBOL(sk_filter_release_rcu);
 
 /**
  *     sk_attach_filter - attach a socket filter
@@ -649,7 +642,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
        rcu_assign_pointer(sk->sk_filter, fp);
 
        if (old_fp)
-               sk_filter_delayed_uncharge(sk, old_fp);
+               sk_filter_uncharge(sk, old_fp);
        return 0;
 }
 EXPORT_SYMBOL_GPL(sk_attach_filter);
@@ -663,7 +656,7 @@ int sk_detach_filter(struct sock *sk)
                                           sock_owned_by_user(sk));
        if (filter) {
                rcu_assign_pointer(sk->sk_filter, NULL);
-               sk_filter_delayed_uncharge(sk, filter);
+               sk_filter_uncharge(sk, filter);
                ret = 0;
        }
        return ret;
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 0ae6c22da85b2a3516980691c8fbcf2f7228e3d6..c19bb4ee405ede196271ac9af5452dd21525fe2e 100644 (file)
@@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
        struct phy_device *phydev;
        unsigned int type;
 
-       skb_push(skb, ETH_HLEN);
+       if (skb_headroom(skb) < ETH_HLEN)
+               return false;
+       __skb_push(skb, ETH_HLEN);
 
        type = classify(skb);
 
-       skb_pull(skb, ETH_HLEN);
+       __skb_pull(skb, ETH_HLEN);
 
        switch (type) {
        case PTP_CLASS_V1_IPV4:
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..15dcc1a586b4a312ee877e78b4e72f1a5e9631e2 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,11 @@ 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)) {
+                       err = -EPERM;
+                       break;
+               }
+
                edev = dev->ec_ptr;
                if (edev == NULL) {
                        /* Magic up a new one. */
@@ -856,9 +851,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len)
 {
        struct iphdr *ip = ip_hdr(skb);
        unsigned char stn = ntohl(ip->saddr) & 0xff;
+       struct dst_entry *dst = skb_dst(skb);
+       struct ec_device *edev = NULL;
        struct sock *sk = NULL;
        struct sk_buff *newskb;
-       struct ec_device *edev = skb->dev->ec_ptr;
+
+       if (dst)
+               edev = dst->dev->ec_ptr;
 
        if (! edev)
                goto bad;
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 1b48eb1ed4531d3fd037e7ee9aa6367b6cb575f3..b14ec7d03b6e70b9a5a1823261ac18cb40462035 100644 (file)
@@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = {
        SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
        SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP),
        SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER),
+       SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
        SNMP_MIB_SENTINEL
 };
 
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 43cf901d765970b6a1a80f167a80ec285a8397b6..a66735f75963582ebc2243e37fd12ca4604be678 100644 (file)
@@ -347,7 +347,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
                 * socket up.  We've got bigger problems than
                 * non-graceful socket closings.
                 */
-               LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n");
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW);
        }
 
        tcp_update_metrics(sk);
index 05b1ecf367632763cbdb1f3bfe0e74c9c4d20c0c..61c2463e2753f809c12f31967e7fa189e41e1f54 100644 (file)
@@ -231,11 +231,10 @@ void tcp_select_initial_window(int __space, __u32 mss,
                /* when initializing use the value from init_rcv_wnd
                 * rather than the default from above
                 */
-               if (init_rcv_wnd &&
-                   (*rcv_wnd > init_rcv_wnd * mss))
-                       *rcv_wnd = init_rcv_wnd * mss;
-               else if (*rcv_wnd > init_cwnd * mss)
-                       *rcv_wnd = init_cwnd * mss;
+               if (init_rcv_wnd)
+                       *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss);
+               else
+                       *rcv_wnd = min(*rcv_wnd, init_cwnd * mss);
        }
 
        /* Set the clamp no higher than max representable value */
@@ -386,27 +385,30 @@ struct tcp_out_options {
  */
 static u8 tcp_cookie_size_check(u8 desired)
 {
-       if (desired > 0) {
+       int cookie_size;
+
+       if (desired > 0)
                /* previously specified */
                return desired;
-       }
-       if (sysctl_tcp_cookie_size <= 0) {
+
+       cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size);
+       if (cookie_size <= 0)
                /* no default specified */
                return 0;
-       }
-       if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) {
+
+       if (cookie_size <= TCP_COOKIE_MIN)
                /* value too small, specify minimum */
                return TCP_COOKIE_MIN;
-       }
-       if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) {
+
+       if (cookie_size >= TCP_COOKIE_MAX)
                /* value too large, specify maximum */
                return TCP_COOKIE_MAX;
-       }
-       if (0x1 & sysctl_tcp_cookie_size) {
+
+       if (cookie_size & 1)
                /* 8-bit multiple, illegal, fix it */
-               return (u8)(sysctl_tcp_cookie_size + 0x1);
-       }
-       return (u8)sysctl_tcp_cookie_size;
+               cookie_size++;
+
+       return (u8)cookie_size;
 }
 
 /* Write previously computed TCP options to the packet.
@@ -1513,6 +1515,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
        struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
        u32 send_win, cong_win, limit, in_flight;
+       int win_divisor;
 
        if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN)
                goto send_now;
@@ -1544,13 +1547,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
        if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len))
                goto send_now;
 
-       if (sysctl_tcp_tso_win_divisor) {
+       win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor);
+       if (win_divisor) {
                u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
 
                /* If at least some fraction of a window is available,
                 * just use it.
                 */
-               chunk /= sysctl_tcp_tso_win_divisor;
+               chunk /= win_divisor;
                if (limit >= chunk)
                        goto send_now;
        } else {
index b41ce0f0d514154597753d549b5a29a3bc7e7ae0..93b7a933a7758254ed70ed849d333ad4d19114a7 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));
@@ -4017,11 +4021,11 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
                kfree_skb(skb);
                goto errout;
        }
-       rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+       rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
        return;
 errout:
        if (err < 0)
-               rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
+               rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
 }
 
 static inline size_t inet6_prefix_nlmsg_size(void)
index 2a59610c2a582ed885ae756729b58da00e6f324f..70e891a20fb9258686b9d9914e6694a3837d0acb 100644 (file)
@@ -1175,6 +1175,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
                                sizeof (struct ipv6hdr);
 
                        dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr);
+                       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+                               dev->mtu-=8;
 
                        if (dev->mtu < IPV6_MIN_MTU)
                                dev->mtu = IPV6_MIN_MTU;
@@ -1363,12 +1365,17 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
 
 static void ip6_tnl_dev_setup(struct net_device *dev)
 {
+       struct ip6_tnl *t;
+
        dev->netdev_ops = &ip6_tnl_netdev_ops;
        dev->destructor = ip6_dev_free;
 
        dev->type = ARPHRD_TUNNEL6;
        dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
        dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
+       t = netdev_priv(dev);
+       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+               dev->mtu-=8;
        dev->flags |= IFF_NOARP;
        dev->addr_len = sizeof(struct in6_addr);
        dev->features |= NETIF_F_NETNS_LOCAL;
index d6bfaec3bbbf1a91701fd31616757af1a565bb41..8c4d00c7cd2bb030c194c19e00b5455d2cddf3df 100644 (file)
@@ -606,8 +606,9 @@ static int ipip6_rcv(struct sk_buff *skb)
                return 0;
        }
 
-       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+       /* no tunnel matched,  let upstream know, ipsec may handle it */
        rcu_read_unlock();
+       return 1;
 out:
        kfree_skb(skb);
        return 0;
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 0bf6a59545ab9439f3ab7126539cd9aef419b752..522e219f3558a3e0e3ad70f27e2de3d09ed8f543 100644 (file)
@@ -674,4 +674,8 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
 MODULE_DESCRIPTION("L2TP over IP");
 MODULE_VERSION("1.0");
-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP);
+
+/* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like
+ * enums
+ */
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP);
index 582612998211d24aa8d4aea919eed1ba1e994db3..e35dbe55f5201c7a8b4b61ffe382766e4abadcb8 100644 (file)
@@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
                goto out;
        rc = -ENODEV;
        rtnl_lock();
+       rcu_read_lock();
        if (sk->sk_bound_dev_if) {
-               llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+               llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
                if (llc->dev) {
                        if (!addr->sllc_arphrd)
                                addr->sllc_arphrd = llc->dev->type;
@@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
                            !llc_mac_match(addr->sllc_mac,
                                           llc->dev->dev_addr)) {
                                rc = -EINVAL;
-                               dev_put(llc->dev);
                                llc->dev = NULL;
                        }
                }
        } else
                llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
                                           addr->sllc_mac);
+       rcu_read_unlock();
        rtnl_unlock();
        if (!llc->dev)
                goto out;
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 902b03ee8f60789bab002691e2db69d1f8c12cf4..54fb4a0e76f03d835c6038cffeabf18874cb2d59 100644 (file)
@@ -2247,6 +2247,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
                break;
        case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
        case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+               if (is_multicast_ether_addr(mgmt->da) &&
+                   !is_broadcast_ether_addr(mgmt->da))
+                       return RX_DROP_MONITOR;
+
                /* process only for station */
                if (sdata->vif.type != NL80211_IFTYPE_STATION)
                        return RX_DROP_MONITOR;
@@ -2741,6 +2745,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 
                        if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
                                return;
+                       goto out;
                }
        }
 
@@ -2780,6 +2785,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                        return;
        }
 
+ out:
        dev_kfree_skb(skb);
 }
 
index 96c594309506432b897b4ab8c749aed4cb3c1349..7a637b80a62ef7a8d00d49285d9d6995b4083d9e 100644 (file)
@@ -1587,7 +1587,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
                                                list) {
                                if (!ieee80211_sdata_running(tmp_sdata))
                                        continue;
-                               if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
+                               if (tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_MONITOR ||
+                                   tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_AP_VLAN ||
+                                       tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_WDS)
                                        continue;
                                if (compare_ether_addr(tmp_sdata->vif.addr,
                                                       hdr->addr2) == 0) {
@@ -1732,15 +1737,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        int nh_pos, h_pos;
        struct sta_info *sta = NULL;
        u32 sta_flags = 0;
+       struct sk_buff *tmp_skb;
 
        if (unlikely(skb->len < ETH_HLEN)) {
                ret = NETDEV_TX_OK;
                goto fail;
        }
 
-       nh_pos = skb_network_header(skb) - skb->data;
-       h_pos = skb_transport_header(skb) - skb->data;
-
        /* convert Ethernet header to proper 802.11 header (based on
         * operation mode) */
        ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1913,6 +1916,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                goto fail;
        }
 
+       /*
+        * If the skb is shared we need to obtain our own copy.
+        */
+       if (skb_shared(skb)) {
+               tmp_skb = skb;
+               skb = skb_copy(skb, GFP_ATOMIC);
+               kfree_skb(tmp_skb);
+
+               if (!skb) {
+                       ret = NETDEV_TX_OK;
+                       goto fail;
+               }
+       }
+
        hdr.frame_control = fc;
        hdr.duration_id = 0;
        hdr.seq_ctrl = 0;
@@ -1931,6 +1948,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                encaps_len = 0;
        }
 
+       nh_pos = skb_network_header(skb) - skb->data;
+       h_pos = skb_transport_header(skb) - skb->data;
+
        skb_pull(skb, skip_header_bytes);
        nh_pos -= skip_header_bytes;
        h_pos -= skip_header_bytes;
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 6bd554323a342d4db49be267766b87492bd2e584..0b9ee34ad35ceb31ff764baf9cec73fba010f55b 100644 (file)
@@ -2932,6 +2932,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
        struct sctp_association *asoc = NULL;
        struct sctp_setpeerprim prim;
        struct sctp_chunk       *chunk;
+       struct sctp_af          *af;
        int                     err;
 
        sp = sctp_sk(sk);
@@ -2959,6 +2960,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
        if (!sctp_state(asoc, ESTABLISHED))
                return -ENOTCONN;
 
+       af = sctp_get_af_specific(prim.sspp_addr.ss_family);
+       if (!af)
+               return -EINVAL;
+
+       if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL))
+               return -EADDRNOTAVAIL;
+
        if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
                return -EADDRNOTAVAIL;
 
index 3ca2fd9e37200e3e12f6606065acb8c982f25528..088fb3fd45e00f3fa5d55e3e374c8751e60d225b 100644 (file)
@@ -732,6 +732,21 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
        return ret;
 }
 
+/**
+ * kernel_recvmsg - Receive a message from a socket (kernel space)
+ * @sock:       The socket to receive the message from
+ * @msg:        Received message
+ * @vec:        Input s/g array for message data
+ * @num:        Size of input s/g array
+ * @size:       Number of bytes to read
+ * @flags:      Message flags (MSG_DONTWAIT, etc...)
+ *
+ * On return the msg structure contains the scatter/gather array passed in the
+ * vec argument. The array is modified so that it consists of the unfilled
+ * portion of the original array.
+ *
+ * The returned value is the total number of bytes received, or an error.
+ */
 int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
                   struct kvec *vec, size_t num, size_t size, int flags)
 {
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..3f2c5559ca1a49a496b9d531625c1e175fb029c8 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>
@@ -213,6 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
        spin_lock(&svc_xprt_class_lock);
        list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
                struct svc_xprt *newxprt;
+               unsigned short newport;
 
                if (strcmp(xprt_name, xcl->xcl_name))
                        continue;
@@ -231,8 +231,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
                spin_lock_bh(&serv->sv_lock);
                list_add(&newxprt->xpt_list, &serv->sv_permsocks);
                spin_unlock_bh(&serv->sv_lock);
+               newport = svc_xprt_local_port(newxprt);
                clear_bit(XPT_BUSY, &newxprt->xpt_flags);
-               return svc_xprt_local_port(newxprt);
+               return newport;
        }
  err:
        spin_unlock(&svc_xprt_class_lock);
@@ -426,8 +427,13 @@ void svc_xprt_received(struct svc_xprt *xprt)
 {
        BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
        xprt->xpt_pool = NULL;
+       /* As soon as we clear busy, the xprt could be closed and
+        * 'put', so we need a reference to call svc_xprt_enqueue with:
+        */
+       svc_xprt_get(xprt);
        clear_bit(XPT_BUSY, &xprt->xpt_flags);
        svc_xprt_enqueue(xprt);
+       svc_xprt_put(xprt);
 }
 EXPORT_SYMBOL_GPL(svc_xprt_received);
 
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 73e7b954ad288229df4d03bc164f07da183444cc..b25c6463c3e996cf536454603f4f0257f3b8b51c 100644 (file)
@@ -394,6 +394,7 @@ void __exit x25_link_free(void)
        list_for_each_safe(entry, tmp, &x25_neigh_list) {
                nb = list_entry(entry, struct x25_neigh, node);
                __x25_remove_neigh(nb);
+               dev_put(nb->dev);
        }
        write_unlock_bh(&x25_neigh_list_lock);
 }
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 eb96ce52f1789dd881116e76a08169189b50f02c..220ebc05c7afc6b602785f6e402d44098cc0bd8d 100644 (file)
@@ -1268,7 +1268,7 @@ struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x,
 
        return xc;
 error:
-       kfree(xc);
+       xfrm_state_put(xc);
        return NULL;
 }
 EXPORT_SYMBOL(xfrm_state_migrate);
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 cb0c23a6b473e07bd9d768f9430e7cde2342639c..4a663471dadc1e1e00d712bd5656577aeba56984 100644 (file)
@@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
        a->channels = GRAB_BITS(buf, 0, 0, 3);
        a->channels++;
 
+       a->sample_bits = 0;
+       a->max_bitrate = 0;
+
        a->format = GRAB_BITS(buf, 0, 3, 4);
        switch (a->format) {
        case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
@@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
 
        case AUDIO_CODING_TYPE_LPCM:
                val = GRAB_BITS(buf, 2, 0, 3);
-               a->sample_bits = 0;
                for (i = 0; i < 3; i++)
                        if (val & (1 << i))
                                a->sample_bits |= cea_sample_sizes[i + 1];
@@ -598,24 +600,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
 {
        int i;
 
-       pcm->rates = 0;
-       pcm->formats = 0;
-       pcm->maxbps = 0;
-       pcm->channels_min = -1;
-       pcm->channels_max = 0;
+       /* assume basic audio support (the basic audio flag is not in ELD;
+        * however, all audio capable sinks are required to support basic
+        * audio) */
+       pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
+       pcm->formats = SNDRV_PCM_FMTBIT_S16_LE;
+       pcm->maxbps = 16;
+       pcm->channels_max = 2;
        for (i = 0; i < eld->sad_count; i++) {
                struct cea_sad *a = &eld->sad[i];
                pcm->rates |= a->rates;
-               if (a->channels < pcm->channels_min)
-                       pcm->channels_min = a->channels;
                if (a->channels > pcm->channels_max)
                        pcm->channels_max = a->channels;
                if (a->format == AUDIO_CODING_TYPE_LPCM) {
-                       if (a->sample_bits & AC_SUPPCM_BITS_16) {
-                               pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE;
-                               if (pcm->maxbps < 16)
-                                       pcm->maxbps = 16;
-                       }
                        if (a->sample_bits & AC_SUPPCM_BITS_20) {
                                pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
                                if (pcm->maxbps < 20)
@@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
        /* restrict the parameters by the values the codec provides */
        pcm->rates &= codec_pars->rates;
        pcm->formats &= codec_pars->formats;
-       pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min);
        pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
        pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
 }
index 21aa9b0e28f6cb466a81a4d1e4c48622c71f89c9..b030c8eba21fdc618fe0b5bfb32cf5b156c39bba 100644 (file)
@@ -2296,6 +2296,7 @@ static int azx_dev_free(struct snd_device *device)
  */
 static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
index 6361f752b5f35cfddff7f8423f0d5d185a9003d8..76bd58a0e2b637e2c17a79cc94ab54e0747de227 100644 (file)
@@ -2116,8 +2116,8 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
        struct conexant_spec *spec = codec->spec;
        unsigned int pinctl;
 
-       snd_printdd("CXT5066: update speaker, hp_present=%d\n",
-               spec->hp_present);
+       snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
+                   spec->hp_present, spec->cur_eapd);
 
        /* Port A (HP) */
        pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
@@ -2125,11 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
                        pinctl);
 
        /* Port D (HP/LO) */
-       pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
-               ? spec->port_d_mode : 0;
-       /* Mute if Port A is connected on Thinkpad */
-       if (spec->thinkpad && (spec->hp_present & 1))
-               pinctl = 0;
+       if (spec->dell_automute) {
+               /* DELL AIO Port Rule: PortA>  PortD>  IntSpk */
+               pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
+                       ? PIN_OUT : 0;
+       } else if (spec->thinkpad) {
+               if (spec->cur_eapd)
+                       pinctl = spec->port_d_mode;
+               /* Mute dock line-out if Port A (laptop HP) is present */
+               if (spec->hp_present&  1)
+                       pinctl = 0;
+       } else {
+               pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
+                       ? spec->port_d_mode : 0;
+       }
        snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
 
@@ -2137,14 +2146,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
        pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
        snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
-
-       if (spec->dell_automute) {
-               /* DELL AIO Port Rule: PortA > PortD > IntSpk */
-               pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
-                       ? PIN_OUT : 0;
-               snd_hda_codec_write(codec, 0x1c, 0,
-                       AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
-       }
 }
 
 /* turn on/off EAPD (+ mute HP) as a master switch */
@@ -3095,11 +3096,11 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
 static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
-       SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
-                     CXT5066_DELL_LAPTOP),
+       SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
        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),
@@ -3108,8 +3109,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
+       SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
        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 d3e49aa5b9ecd42f6db6f5892319e6602ad9b7ab..31df7747990d0be6690a520321a0498c9caba349 100644 (file)
@@ -834,7 +834,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
                        return -ENODEV;
        } else {
                /* fallback to the codec default */
-               hinfo->channels_min = codec_pars->channels_min;
                hinfo->channels_max = codec_pars->channels_max;
                hinfo->rates = codec_pars->rates;
                hinfo->formats = codec_pars->formats;
index 5f00589cb791aebed2d7aa1f0bd908819b9123b8..2d7d7de8498a7947bb9c6180bc757017535c343c 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;
@@ -4554,6 +4595,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
        SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
+       SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
        SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
        SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
        SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
@@ -9524,13 +9566,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 +9866,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 +10362,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 +14657,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 +15060,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 +15071,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 +15150,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 +16944,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 +18998,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 +19008,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 +19346,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 +19468,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 +19961,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 a2e0ed59b3769f0b7d73024a6e4740338b1ccb81..879dff2714dd3c522211dbac3c636a5191d8ce4b 100644 (file)
@@ -491,16 +491,16 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
                paifa |= 0x8;
                break;
        case SNDRV_PCM_FORMAT_S20_3LE:
-               paifa |= 0x10;
+               paifa |= 0x0;
                paifb |= WM8580_AIF_LENGTH_20;
                break;
        case SNDRV_PCM_FORMAT_S24_LE:
-               paifa |= 0x10;
+               paifa |= 0x0;
                paifb |= WM8580_AIF_LENGTH_24;
                break;
        case SNDRV_PCM_FORMAT_S32_LE:
-               paifa |= 0x10;
-               paifb |= WM8580_AIF_LENGTH_24;
+               paifa |= 0x0;
+               paifb |= WM8580_AIF_LENGTH_32;
                break;
        default:
                return -EINVAL;
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..1304ca91a11c708c567f69c45052c95f1f7be17e 100644 (file)
@@ -3339,7 +3339,7 @@ static irqreturn_t wm8962_irq(int irq, void *data)
        int mask;
        int active;
 
-       mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
+       mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
 
        active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
        active &= ~mask;
@@ -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 19ca782ac970f1956243862534e5df1df12a3113..0e24092722c39522d85980a71f8a3727d01cf63f 100644 (file)
@@ -293,7 +293,7 @@ SOC_DOUBLE_R("Speaker Switch",
 SOC_DOUBLE_R("Speaker ZC Switch",
             WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
             7, 1, 0),
-SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0,
+SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
               spkboost_tlv),
 SOC_ENUM("Speaker Reference", speaker_ref),
 SOC_ENUM("Speaker Mode", speaker_mode),
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..85b7d548f1675f14c1a2065bbcffcf7d229a2e27 100644 (file)
@@ -1619,12 +1619,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 #ifdef CONFIG_SND_SOC_AC97_BUS
        /* register any AC97 codecs */
        for (i = 0; i < card->num_rtd; i++) {
-                       ret = soc_register_ac97_dai_link(&card->rtd[i]);
-                       if (ret < 0) {
-                               printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
-                               goto probe_dai_err;
-                       }
+               ret = soc_register_ac97_dai_link(&card->rtd[i]);
+               if (ret < 0) {
+                       printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
+                       while (--i >= 0)
+                               soc_unregister_ac97_dai_link(&card->rtd[i]);
+                       goto probe_dai_err;
                }
+       }
 #endif
 
        card->instantiated = 1;
@@ -3043,8 +3045,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]);
@@ -3070,7 +3074,9 @@ int snd_soc_register_dais(struct device *dev,
                pr_debug("Registered DAI '%s'\n", dai->name);
        }
 
+       mutex_lock(&client_mutex);
        snd_soc_instantiate_cards();
+       mutex_unlock(&client_mutex);
        return 0;
 
 err:
@@ -3263,9 +3269,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 93bd2ff001fb113ff11159e419269942ac4e3743..564491fa18b27838dd79125954bc744f51f7fe2c 100644 (file)
@@ -197,7 +197,7 @@ static void sig_atexit(void)
        if (child_pid > 0)
                kill(child_pid, SIGTERM);
 
-       if (signr == -1)
+       if (signr == -1 || signr == SIGUSR1)
                return;
 
        signal(signr, SIG_DFL);
@@ -515,6 +515,7 @@ static int __cmd_record(int argc, const char **argv)
        atexit(sig_atexit);
        signal(SIGCHLD, sig_handler);
        signal(SIGINT, sig_handler);
+       signal(SIGUSR1, sig_handler);
 
        if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
                perror("failed to create pipes");
@@ -606,6 +607,7 @@ static int __cmd_record(int argc, const char **argv)
                        execvp(argv[0], (char **)argv);
 
                        perror(argv[0]);
+                       kill(getppid(), SIGUSR1);
                        exit(-1);
                }
 
@@ -697,17 +699,18 @@ static int __cmd_record(int argc, const char **argv)
        if (err < 0)
                err = event__synthesize_kernel_mmap(process_synthesized_event,
                                                    session, machine, "_stext");
-       if (err < 0) {
-               pr_err("Couldn't record kernel reference relocation symbol.\n");
-               return err;
-       }
+       if (err < 0)
+               pr_err("Couldn't record kernel reference relocation symbol\n"
+                      "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
+                      "Check /proc/kallsyms permission or run as root.\n");
 
        err = event__synthesize_modules(process_synthesized_event,
                                        session, machine);
-       if (err < 0) {
-               pr_err("Couldn't record kernel reference relocation symbol.\n");
-               return err;
-       }
+       if (err < 0)
+               pr_err("Couldn't record kernel module information.\n"
+                      "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
+                      "Check /proc/modules permission or run as root.\n");
+
        if (perf_guest)
                perf_session__process_machines(session, event__synthesize_guest_os);
 
@@ -761,7 +764,7 @@ static int __cmd_record(int argc, const char **argv)
                }
        }
 
-       if (quiet)
+       if (quiet || signr == SIGUSR1)
                return 0;
 
        fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
index d7e67b167ea338a28fed519260f1069dd8e92cf9..64a85bafde63a1c6f05451a32b31eec521c799d9 100644 (file)
@@ -946,11 +946,16 @@ perf_header__find_attr(u64 id, struct perf_header *header)
 
        /*
         * We set id to -1 if the data file doesn't contain sample
-        * ids. Check for this and avoid walking through the entire
-        * list of ids which may be large.
+        * ids. This can happen when the data file contains one type
+        * of event and in that case, the header can still store the
+        * event attribute information. Check for this and avoid
+        * walking through the entire list of ids which may be large.
         */
-       if (id == -1ULL)
+       if (id == -1ULL) {
+               if (header->attrs > 0)
+                       return &header->attr[0]->attr;
                return NULL;
+       }
 
        for (i = 0; i < header->attrs; i++) {
                struct perf_header_attr *attr = header->attr[i];
index b39f499e575a604198bf1bb11d11d6280a091548..d628c8d1cf5ec11111ab3b750da0d14f6d8fff7f 100644 (file)
@@ -295,7 +295,9 @@ static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
 {
        struct rb_node **p = &self->rb_node;
        struct rb_node *parent = NULL;
-       struct symbol_name_rb_node *symn = ((void *)sym) - sizeof(*parent), *s;
+       struct symbol_name_rb_node *symn, *s;
+
+       symn = container_of(sym, struct symbol_name_rb_node, sym);
 
        while (*p != NULL) {
                parent = *p;
@@ -530,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
        struct machine *machine = kmaps->machine;
        struct map *curr_map = map;
        struct symbol *pos;
-       int count = 0;
+       int count = 0, moved = 0;       
        struct rb_root *root = &self->symbols[map->type];
        struct rb_node *next = rb_first(root);
        int kernel_range = 0;
@@ -588,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        char dso_name[PATH_MAX];
                        struct dso *dso;
 
+                       if (count == 0) {
+                               curr_map = map;
+                               goto filter_symbol;
+                       }
+
                        if (self->kernel == DSO_TYPE_GUEST_KERNEL)
                                snprintf(dso_name, sizeof(dso_name),
                                        "[guest.kernel].%d",
@@ -613,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        map_groups__insert(kmaps, curr_map);
                        ++kernel_range;
                }
-
+filter_symbol:
                if (filter && filter(curr_map, pos)) {
 discard_symbol:                rb_erase(&pos->rb_node, root);
                        symbol__delete(pos);
@@ -621,8 +628,9 @@ discard_symbol:             rb_erase(&pos->rb_node, root);
                        if (curr_map != map) {
                                rb_erase(&pos->rb_node, root);
                                symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
-                       }
-                       count++;
+                               ++moved;
+                       } else
+                               ++count;
                }
        }
 
@@ -632,7 +640,7 @@ discard_symbol:             rb_erase(&pos->rb_node, root);
                dso__set_loaded(curr_map->dso, curr_map->type);
        }
 
-       return count;
+       return count + moved;
 }
 
 int dso__load_kallsyms(struct dso *self, const char *filename,
@@ -2123,14 +2131,55 @@ static struct dso *machine__create_kernel(struct machine *self)
        return kernel;
 }
 
+struct process_args {
+       u64 start;
+};
+
+static int symbol__in_kernel(void *arg, const char *name,
+                            char type __used, u64 start)
+{
+       struct process_args *args = arg;
+
+       if (strchr(name, '['))
+               return 0;
+
+       args->start = start;
+       return 1;
+}
+
+/* Figure out the start address of kernel map from /proc/kallsyms */
+static u64 machine__get_kernel_start_addr(struct machine *machine)
+{
+       const char *filename;
+       char path[PATH_MAX];
+       struct process_args args;
+
+       if (machine__is_host(machine)) {
+               filename = "/proc/kallsyms";
+       } else {
+               if (machine__is_default_guest(machine))
+                       filename = (char *)symbol_conf.default_guest_kallsyms;
+               else {
+                       sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+                       filename = path;
+               }
+       }
+
+       if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
+               return 0;
+
+       return args.start;
+}
+
 int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
 {
        enum map_type type;
+       u64 start = machine__get_kernel_start_addr(self);
 
        for (type = 0; type < MAP__NR_TYPES; ++type) {
                struct kmap *kmap;
 
-               self->vmlinux_maps[type] = map__new2(0, kernel, type);
+               self->vmlinux_maps[type] = map__new2(start, kernel, type);
                if (self->vmlinux_maps[type] == NULL)
                        return -1;
 
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